@@ -29,6 +29,7 @@ use mz_storage_client::controller::StorageError;
29
29
use mz_transform:: TransformError ;
30
30
use smallvec:: SmallVec ;
31
31
use tokio:: sync:: oneshot;
32
+ use tokio_postgres:: error:: SqlState ;
32
33
33
34
use crate :: { catalog, rbac} ;
34
35
@@ -345,6 +346,104 @@ impl AdapterError {
345
346
}
346
347
}
347
348
349
+ pub fn code ( & self ) -> SqlState {
350
+ // TODO(benesch): we should only use `SqlState::INTERNAL_ERROR` for
351
+ // those errors that are truly internal errors. At the moment we have
352
+ // a various classes of uncategorized errors that use this error code
353
+ // inappropriately.
354
+ match self {
355
+ // DATA_EXCEPTION to match what Postgres returns for degenerate
356
+ // range bounds
357
+ AdapterError :: AbsurdSubscribeBounds { .. } => SqlState :: DATA_EXCEPTION ,
358
+ AdapterError :: AmbiguousSystemColumnReference => SqlState :: FEATURE_NOT_SUPPORTED ,
359
+ AdapterError :: BadItemInStorageCluster { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
360
+ AdapterError :: Catalog ( _) => SqlState :: INTERNAL_ERROR ,
361
+ AdapterError :: ChangedPlan => SqlState :: FEATURE_NOT_SUPPORTED ,
362
+ AdapterError :: DuplicateCursor ( _) => SqlState :: DUPLICATE_CURSOR ,
363
+ AdapterError :: Eval ( EvalError :: CharacterNotValidForEncoding ( _) ) => {
364
+ SqlState :: PROGRAM_LIMIT_EXCEEDED
365
+ }
366
+ AdapterError :: Eval ( EvalError :: CharacterTooLargeForEncoding ( _) ) => {
367
+ SqlState :: PROGRAM_LIMIT_EXCEEDED
368
+ }
369
+ AdapterError :: Eval ( EvalError :: LengthTooLarge ) => SqlState :: PROGRAM_LIMIT_EXCEEDED ,
370
+ AdapterError :: Eval ( EvalError :: NullCharacterNotPermitted ) => {
371
+ SqlState :: PROGRAM_LIMIT_EXCEEDED
372
+ }
373
+ AdapterError :: Eval ( _) => SqlState :: INTERNAL_ERROR ,
374
+ AdapterError :: Explain ( _) => SqlState :: INTERNAL_ERROR ,
375
+ AdapterError :: IdExhaustionError => SqlState :: INTERNAL_ERROR ,
376
+ AdapterError :: Internal ( _) => SqlState :: INTERNAL_ERROR ,
377
+ AdapterError :: IntrospectionDisabled { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
378
+ AdapterError :: InvalidLogDependency { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
379
+ AdapterError :: InvalidClusterReplicaAz { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
380
+ AdapterError :: InvalidClusterReplicaSize { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
381
+ AdapterError :: InvalidSetIsolationLevel => SqlState :: ACTIVE_SQL_TRANSACTION ,
382
+ AdapterError :: InvalidStorageClusterSize { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
383
+ AdapterError :: SourceOrSinkSizeRequired { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
384
+ AdapterError :: InvalidTableMutationSelection => SqlState :: INVALID_TRANSACTION_STATE ,
385
+ AdapterError :: ConstraintViolation ( NotNullViolation ( _) ) => SqlState :: NOT_NULL_VIOLATION ,
386
+ AdapterError :: NoClusterReplicasAvailable ( _) => SqlState :: FEATURE_NOT_SUPPORTED ,
387
+ AdapterError :: OperationProhibitsTransaction ( _) => SqlState :: ACTIVE_SQL_TRANSACTION ,
388
+ AdapterError :: OperationRequiresTransaction ( _) => SqlState :: NO_ACTIVE_SQL_TRANSACTION ,
389
+ AdapterError :: ParseError ( _) => SqlState :: SYNTAX_ERROR ,
390
+ AdapterError :: PlanError ( PlanError :: InvalidSchemaName ) => SqlState :: INVALID_SCHEMA_NAME ,
391
+ AdapterError :: PlanError ( _) => SqlState :: INTERNAL_ERROR ,
392
+ AdapterError :: PreparedStatementExists ( _) => SqlState :: DUPLICATE_PSTATEMENT ,
393
+ AdapterError :: ReadOnlyTransaction => SqlState :: READ_ONLY_SQL_TRANSACTION ,
394
+ AdapterError :: ReadWriteUnavailable => SqlState :: INVALID_TRANSACTION_STATE ,
395
+ AdapterError :: StatementTimeout => SqlState :: QUERY_CANCELED ,
396
+ AdapterError :: Canceled => SqlState :: QUERY_CANCELED ,
397
+ AdapterError :: IdleInTransactionSessionTimeout => {
398
+ SqlState :: IDLE_IN_TRANSACTION_SESSION_TIMEOUT
399
+ }
400
+ AdapterError :: RecursionLimit ( _) => SqlState :: INTERNAL_ERROR ,
401
+ AdapterError :: RelationOutsideTimeDomain { .. } => SqlState :: INVALID_TRANSACTION_STATE ,
402
+ AdapterError :: ResourceExhaustion { .. } => SqlState :: INSUFFICIENT_RESOURCES ,
403
+ AdapterError :: ResultSize ( _) => SqlState :: OUT_OF_MEMORY ,
404
+ AdapterError :: SafeModeViolation ( _) => SqlState :: INTERNAL_ERROR ,
405
+ AdapterError :: SqlCatalog ( _) => SqlState :: INTERNAL_ERROR ,
406
+ AdapterError :: SubscribeOnlyTransaction => SqlState :: INVALID_TRANSACTION_STATE ,
407
+ AdapterError :: Transform ( _) => SqlState :: INTERNAL_ERROR ,
408
+ AdapterError :: UnallowedOnCluster { .. } => {
409
+ SqlState :: S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED
410
+ }
411
+ AdapterError :: Unauthorized ( _) => SqlState :: INSUFFICIENT_PRIVILEGE ,
412
+ AdapterError :: UncallableFunction { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
413
+ AdapterError :: UnknownCursor ( _) => SqlState :: INVALID_CURSOR_NAME ,
414
+ AdapterError :: UnknownPreparedStatement ( _) => SqlState :: UNDEFINED_PSTATEMENT ,
415
+ AdapterError :: UnknownLoginRole ( _) => SqlState :: INVALID_AUTHORIZATION_SPECIFICATION ,
416
+ AdapterError :: UnknownClusterReplica { .. } => SqlState :: UNDEFINED_OBJECT ,
417
+ AdapterError :: UnmaterializableFunction ( _) => SqlState :: FEATURE_NOT_SUPPORTED ,
418
+ AdapterError :: UnrecognizedConfigurationParam ( _) => SqlState :: UNDEFINED_OBJECT ,
419
+ AdapterError :: UnstableDependency { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
420
+ AdapterError :: Unsupported ( ..) => SqlState :: FEATURE_NOT_SUPPORTED ,
421
+ AdapterError :: Unstructured ( _) => SqlState :: INTERNAL_ERROR ,
422
+ AdapterError :: UntargetedLogRead { .. } => SqlState :: FEATURE_NOT_SUPPORTED ,
423
+ // It's not immediately clear which error code to use here because a
424
+ // "write-only transaction" and "single table write transaction" are
425
+ // not things in Postgres. This error code is the generic "bad txn thing"
426
+ // code, so it's probably the best choice.
427
+ AdapterError :: WriteOnlyTransaction => SqlState :: INVALID_TRANSACTION_STATE ,
428
+ AdapterError :: MultiTableWriteTransaction => SqlState :: INVALID_TRANSACTION_STATE ,
429
+ AdapterError :: Storage ( _) | AdapterError :: Compute ( _) | AdapterError :: Orchestrator ( _) => {
430
+ SqlState :: INTERNAL_ERROR
431
+ }
432
+ AdapterError :: ConcurrentRoleDrop ( _) => SqlState :: UNDEFINED_OBJECT ,
433
+ AdapterError :: DependentObject ( _) => SqlState :: DEPENDENT_OBJECTS_STILL_EXIST ,
434
+ AdapterError :: VarError ( e) => match e {
435
+ VarError :: ConstrainedParameter { .. } => SqlState :: INVALID_PARAMETER_VALUE ,
436
+ VarError :: FixedValueParameter ( _) => SqlState :: INVALID_PARAMETER_VALUE ,
437
+ VarError :: InvalidParameterType ( _) => SqlState :: INVALID_PARAMETER_VALUE ,
438
+ VarError :: InvalidParameterValue { .. } => SqlState :: INVALID_PARAMETER_VALUE ,
439
+ VarError :: ReadOnlyParameter ( _) => SqlState :: CANT_CHANGE_RUNTIME_PARAM ,
440
+ VarError :: UnknownParameter ( _) => SqlState :: UNDEFINED_OBJECT ,
441
+ VarError :: RequiresUnsafeMode { .. } => SqlState :: CANT_CHANGE_RUNTIME_PARAM ,
442
+ VarError :: RequiresFeatureFlag { .. } => SqlState :: CANT_CHANGE_RUNTIME_PARAM ,
443
+ } ,
444
+ }
445
+ }
446
+
348
447
pub fn internal < E : std:: fmt:: Display > ( context : & str , e : E ) -> AdapterError {
349
448
AdapterError :: Internal ( format ! ( "{context}: {e}" ) )
350
449
}
0 commit comments