Skip to main content

icydb_diagnostic_code/
lib.rs

1//! Compact diagnostic identity for IcyDB.
2//!
3//! This crate intentionally contains no rich diagnostic prose or Candid wire
4//! types. Production canister builds collapse diagnostics to numeric wire
5//! codes before they cross the public canister boundary.
6
7///
8/// DiagnosticCode
9///
10/// Stable machine-readable diagnostic reason.
11///
12
13#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
14pub enum DiagnosticCode {
15    QueryValidate,
16    QueryIntent,
17    QueryPlan,
18    QueryAccessRequirement,
19    QueryUnorderedPagination,
20    QueryInvalidContinuationCursor,
21    QueryNotFound,
22    QueryNotUnique,
23    QueryNumericOverflow,
24    QueryNumericNotRepresentable,
25    QueryUnknownAggregateTargetField,
26    QueryUnsupportedProjection,
27    QueryResultShapeMismatch,
28    QueryUnsupportedSqlFeature,
29    QuerySqlSurfaceMismatch,
30    QuerySqlWriteBoundary,
31    SchemaDdlAdmission,
32    StoreNotFound,
33    StoreCorruption,
34    StoreInvariantViolation,
35    RuntimeCorruption,
36    RuntimeIncompatiblePersistedFormat,
37    RuntimeInvariantViolation,
38    RuntimeConflict,
39    RuntimeNotFound,
40    RuntimeUnsupported,
41    RuntimeInternal,
42}
43
44impl DiagnosticCode {
45    /// Return the broad diagnostic class for this code.
46    #[must_use]
47    pub const fn class(self) -> ErrorClass {
48        match self {
49            Self::StoreCorruption | Self::RuntimeCorruption => ErrorClass::Corruption,
50            Self::RuntimeIncompatiblePersistedFormat => ErrorClass::IncompatiblePersistedFormat,
51            Self::QueryNotFound | Self::StoreNotFound | Self::RuntimeNotFound => {
52                ErrorClass::NotFound
53            }
54            Self::RuntimeConflict => ErrorClass::Conflict,
55            Self::QueryUnsupportedSqlFeature
56            | Self::QueryUnknownAggregateTargetField
57            | Self::QueryUnsupportedProjection
58            | Self::QueryResultShapeMismatch
59            | Self::QuerySqlSurfaceMismatch
60            | Self::QuerySqlWriteBoundary
61            | Self::RuntimeUnsupported => ErrorClass::Unsupported,
62            Self::StoreInvariantViolation | Self::RuntimeInvariantViolation => {
63                ErrorClass::InvariantViolation
64            }
65            Self::RuntimeInternal => ErrorClass::Internal,
66            Self::QueryValidate
67            | Self::QueryIntent
68            | Self::QueryPlan
69            | Self::QueryAccessRequirement
70            | Self::QueryUnorderedPagination
71            | Self::QueryInvalidContinuationCursor
72            | Self::QueryNotUnique
73            | Self::QueryNumericOverflow
74            | Self::QueryNumericNotRepresentable
75            | Self::SchemaDdlAdmission => ErrorClass::Query,
76        }
77    }
78
79    /// Return the default diagnostic origin for this code.
80    #[must_use]
81    pub const fn origin(self) -> ErrorOrigin {
82        match self {
83            Self::StoreNotFound | Self::StoreCorruption | Self::StoreInvariantViolation => {
84                ErrorOrigin::Store
85            }
86            Self::RuntimeCorruption
87            | Self::RuntimeIncompatiblePersistedFormat
88            | Self::RuntimeInvariantViolation
89            | Self::RuntimeConflict
90            | Self::RuntimeNotFound
91            | Self::RuntimeUnsupported
92            | Self::RuntimeInternal => ErrorOrigin::Runtime,
93            Self::QueryValidate
94            | Self::QueryIntent
95            | Self::QueryPlan
96            | Self::QueryAccessRequirement
97            | Self::QueryUnorderedPagination
98            | Self::QueryInvalidContinuationCursor
99            | Self::QueryNotFound
100            | Self::QueryNotUnique
101            | Self::QueryNumericOverflow
102            | Self::QueryNumericNotRepresentable
103            | Self::QueryUnknownAggregateTargetField
104            | Self::QueryUnsupportedProjection
105            | Self::QueryResultShapeMismatch
106            | Self::QueryUnsupportedSqlFeature
107            | Self::QuerySqlSurfaceMismatch
108            | Self::QuerySqlWriteBoundary
109            | Self::SchemaDdlAdmission => ErrorOrigin::Query,
110        }
111    }
112
113    /// Return the compact public wire code for this broad diagnostic reason.
114    #[must_use]
115    pub const fn error_code(self) -> ErrorCode {
116        match self {
117            Self::QueryValidate => ErrorCode::QUERY_VALIDATE,
118            Self::QueryIntent => ErrorCode::QUERY_INTENT,
119            Self::QueryPlan => ErrorCode::QUERY_PLAN,
120            Self::QueryAccessRequirement => ErrorCode::QUERY_ACCESS_REQUIREMENT,
121            Self::QueryUnorderedPagination => ErrorCode::QUERY_UNORDERED_PAGINATION,
122            Self::QueryInvalidContinuationCursor => ErrorCode::QUERY_INVALID_CONTINUATION_CURSOR,
123            Self::QueryNotFound => ErrorCode::QUERY_NOT_FOUND,
124            Self::QueryNotUnique => ErrorCode::QUERY_NOT_UNIQUE,
125            Self::QueryNumericOverflow => ErrorCode::QUERY_NUMERIC_OVERFLOW,
126            Self::QueryNumericNotRepresentable => ErrorCode::QUERY_NUMERIC_NOT_REPRESENTABLE,
127            Self::QueryUnknownAggregateTargetField => {
128                ErrorCode::QUERY_UNKNOWN_AGGREGATE_TARGET_FIELD
129            }
130            Self::QueryUnsupportedProjection => ErrorCode::QUERY_UNSUPPORTED_PROJECTION,
131            Self::QueryResultShapeMismatch => ErrorCode::QUERY_RESULT_SHAPE_MISMATCH,
132            Self::QueryUnsupportedSqlFeature => ErrorCode::QUERY_UNSUPPORTED_SQL_FEATURE,
133            Self::QuerySqlSurfaceMismatch => ErrorCode::QUERY_SQL_SURFACE_MISMATCH,
134            Self::QuerySqlWriteBoundary => ErrorCode::QUERY_SQL_WRITE_BOUNDARY,
135            Self::SchemaDdlAdmission => ErrorCode::SCHEMA_DDL_ADMISSION,
136            Self::StoreNotFound => ErrorCode::STORE_NOT_FOUND,
137            Self::StoreCorruption => ErrorCode::STORE_CORRUPTION,
138            Self::StoreInvariantViolation => ErrorCode::STORE_INVARIANT_VIOLATION,
139            Self::RuntimeCorruption => ErrorCode::RUNTIME_CORRUPTION,
140            Self::RuntimeIncompatiblePersistedFormat => {
141                ErrorCode::RUNTIME_INCOMPATIBLE_PERSISTED_FORMAT
142            }
143            Self::RuntimeInvariantViolation => ErrorCode::RUNTIME_INVARIANT_VIOLATION,
144            Self::RuntimeConflict => ErrorCode::RUNTIME_CONFLICT,
145            Self::RuntimeNotFound => ErrorCode::RUNTIME_NOT_FOUND,
146            Self::RuntimeUnsupported => ErrorCode::RUNTIME_UNSUPPORTED,
147            Self::RuntimeInternal => ErrorCode::RUNTIME_INTERNAL,
148        }
149    }
150}
151
152///
153/// ErrorCode
154///
155/// Stable numeric public error identity.
156///
157/// The public Candid `icydb::Error` stores this value as `nat16` so canister
158/// interfaces do not retain rich diagnostic enum labels. Rich diagnostics can
159/// still be reconstructed by host-side tooling from this leaf code. Before
160/// 1.0.0, the code space is hard-cut to a single compact sequential range.
161///
162
163#[derive(Clone, Copy, Eq, Hash, PartialEq)]
164pub struct ErrorCode(u16);
165
166impl ErrorCode {
167    pub const QUERY_VALIDATE: Self = Self(1);
168    pub const QUERY_INTENT: Self = Self(2);
169    pub const QUERY_PLAN: Self = Self(3);
170    pub const QUERY_ACCESS_REQUIREMENT: Self = Self(4);
171    pub const QUERY_UNORDERED_PAGINATION: Self = Self(5);
172    pub const QUERY_INVALID_CONTINUATION_CURSOR: Self = Self(6);
173    pub const QUERY_NOT_FOUND: Self = Self(7);
174    pub const QUERY_NOT_UNIQUE: Self = Self(8);
175    pub const QUERY_NUMERIC_OVERFLOW: Self = Self(9);
176    pub const QUERY_NUMERIC_NOT_REPRESENTABLE: Self = Self(10);
177    pub const QUERY_UNKNOWN_AGGREGATE_TARGET_FIELD: Self = Self(11);
178    pub const QUERY_UNSUPPORTED_SQL_FEATURE: Self = Self(12);
179    pub const QUERY_SQL_SURFACE_MISMATCH: Self = Self(13);
180    pub const SCHEMA_DDL_ADMISSION: Self = Self(14);
181    pub const STORE_NOT_FOUND: Self = Self(15);
182    pub const STORE_CORRUPTION: Self = Self(16);
183    pub const STORE_INVARIANT_VIOLATION: Self = Self(17);
184    pub const RUNTIME_CORRUPTION: Self = Self(18);
185    pub const RUNTIME_INCOMPATIBLE_PERSISTED_FORMAT: Self = Self(19);
186    pub const RUNTIME_INVARIANT_VIOLATION: Self = Self(20);
187    pub const RUNTIME_CONFLICT: Self = Self(21);
188    pub const RUNTIME_NOT_FOUND: Self = Self(22);
189    pub const RUNTIME_UNSUPPORTED: Self = Self(23);
190    pub const RUNTIME_INTERNAL: Self = Self(24);
191
192    pub const RUNTIME_BOUNDARY_SQL_SURFACE_CONTROLLER_REQUIRED: Self = Self(25);
193    pub const RUNTIME_BOUNDARY_SCHEMA_SURFACE_CONTROLLER_REQUIRED: Self = Self(26);
194    pub const RUNTIME_BOUNDARY_SQL_QUERY_NO_CONFIGURED_ENTITIES: Self = Self(27);
195    pub const RUNTIME_BOUNDARY_SQL_QUERY_ENTITY_NOT_CONFIGURED: Self = Self(28);
196    pub const RUNTIME_BOUNDARY_SQL_DDL_TARGET_REQUIRED: Self = Self(29);
197    pub const RUNTIME_BOUNDARY_SQL_DDL_ENTITY_NOT_CONFIGURED: Self = Self(30);
198    pub const RUNTIME_BOUNDARY_QUERY_RESPONSE_ROWS_REQUIRED: Self = Self(31);
199    pub const RUNTIME_BOUNDARY_QUERY_RESPONSE_GROUPED_ROWS_REQUIRED: Self = Self(32);
200    pub const RUNTIME_BOUNDARY_MUTATION_RESULT_ENTITY_REQUIRED: Self = Self(33);
201    pub const RUNTIME_BOUNDARY_MUTATION_RESULT_ENTITIES_REQUIRED: Self = Self(34);
202    pub const RUNTIME_BOUNDARY_MUTATION_RESULT_ID_REQUIRED: Self = Self(35);
203    pub const RUNTIME_BOUNDARY_MUTATION_RESULT_IDS_REQUIRED: Self = Self(36);
204    pub const RUNTIME_BOUNDARY_ROW_PROJECTION_FIELD_NOT_CONFIGURED: Self = Self(37);
205
206    pub const SQL_FEATURE_AGGREGATE_FILTER_CLAUSE: Self = Self(38);
207    pub const SQL_FEATURE_ALTER_STATEMENT_BEYOND_ALTER_TABLE: Self = Self(39);
208    pub const SQL_FEATURE_ALTER_TABLE_ADD_COLUMN_DUPLICATE_DEFAULT: Self = Self(40);
209    pub const SQL_FEATURE_ALTER_TABLE_ADD_COLUMN_MODIFIERS: Self = Self(41);
210    pub const SQL_FEATURE_ALTER_TABLE_ADD_STATEMENT_BEYOND_ADD_COLUMN: Self = Self(42);
211    pub const SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_DROP_UNSUPPORTED_ACTION: Self = Self(43);
212    pub const SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_MODIFIERS: Self = Self(44);
213    pub const SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_SET_UNSUPPORTED_ACTION: Self = Self(45);
214    pub const SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_UNSUPPORTED_ACTION: Self = Self(46);
215    pub const SQL_FEATURE_ALTER_TABLE_ALTER_STATEMENT_BEYOND_ALTER_COLUMN: Self = Self(47);
216    pub const SQL_FEATURE_ALTER_TABLE_DROP_COLUMN_IF_EXISTS_SYNTAX: Self = Self(48);
217    pub const SQL_FEATURE_ALTER_TABLE_DROP_COLUMN_MODIFIERS: Self = Self(49);
218    pub const SQL_FEATURE_ALTER_TABLE_DROP_STATEMENT_BEYOND_DROP_COLUMN: Self = Self(50);
219    pub const SQL_FEATURE_ALTER_TABLE_RENAME_COLUMN_MISSING_TO: Self = Self(51);
220    pub const SQL_FEATURE_ALTER_TABLE_RENAME_COLUMN_MODIFIERS: Self = Self(52);
221    pub const SQL_FEATURE_ALTER_TABLE_RENAME_STATEMENT_BEYOND_RENAME_COLUMN: Self = Self(53);
222    pub const SQL_FEATURE_ALTER_TABLE_UNSUPPORTED_OPERATION: Self = Self(54);
223    pub const SQL_FEATURE_COLUMN_ALIAS: Self = Self(55);
224    pub const SQL_FEATURE_CREATE_INDEX_IF_NOT_EXISTS_SYNTAX: Self = Self(56);
225    pub const SQL_FEATURE_CREATE_INDEX_KEY_ORDERING_MODIFIERS: Self = Self(57);
226    pub const SQL_FEATURE_CREATE_INDEX_MODIFIERS: Self = Self(58);
227    pub const SQL_FEATURE_CREATE_STATEMENT_BEYOND_CREATE_INDEX: Self = Self(59);
228    pub const SQL_FEATURE_DESCRIBE_MODIFIER: Self = Self(60);
229    pub const SQL_FEATURE_DDL_SCHEMA_VERSION_DUPLICATE_EXPECTED_CLAUSE: Self = Self(61);
230    pub const SQL_FEATURE_DDL_SCHEMA_VERSION_DUPLICATE_SET_CLAUSE: Self = Self(62);
231    pub const SQL_FEATURE_DROP_INDEX_MODIFIERS: Self = Self(63);
232    pub const SQL_FEATURE_DROP_INDEX_IF_EXISTS_SYNTAX: Self = Self(64);
233    pub const SQL_FEATURE_DROP_STATEMENT_BEYOND_DROP_INDEX: Self = Self(65);
234    pub const SQL_FEATURE_EXPRESSION_INDEX_UNSUPPORTED_FUNCTION: Self = Self(66);
235    pub const SQL_FEATURE_HAVING: Self = Self(67);
236    pub const SQL_FEATURE_INSERT: Self = Self(68);
237    pub const SQL_FEATURE_JOIN: Self = Self(69);
238    pub const SQL_FEATURE_LIKE_PATTERN_BEYOND_TRAILING_PREFIX: Self = Self(70);
239    pub const SQL_FEATURE_LOWER_FIELD_PREDICATE_UNSUPPORTED: Self = Self(71);
240    pub const SQL_FEATURE_MULTI_STATEMENT_SQL: Self = Self(72);
241    pub const SQL_FEATURE_NESTED_AGGREGATE_INPUT: Self = Self(73);
242    pub const SQL_FEATURE_NESTED_PROJECTION_FUNCTION_IN_ARITHMETIC: Self = Self(74);
243    pub const SQL_FEATURE_ORDER_BY_UNSUPPORTED_FORM: Self = Self(75);
244    pub const SQL_FEATURE_OTHER: Self = Self(76);
245    pub const SQL_FEATURE_PARAMETER_BINDING: Self = Self(77);
246    pub const SQL_FEATURE_PARAMETERIZED_SCHEMA_VERSION: Self = Self(78);
247    pub const SQL_FEATURE_PREDICATE_STARTS_WITH_FIRST_ARGUMENT: Self = Self(79);
248    pub const SQL_FEATURE_QUOTED_IDENTIFIERS: Self = Self(80);
249    pub const SQL_FEATURE_RETURNING_UNSUPPORTED_SHAPE: Self = Self(81);
250    pub const SQL_FEATURE_SCALAR_FUNCTION_EXPRESSION_POSITION: Self = Self(82);
251    pub const SQL_FEATURE_SCALE_TAKING_NUMERIC_FUNCTION_EXPRESSION_POSITION: Self = Self(83);
252    pub const SQL_FEATURE_SEARCHED_CASE_GROUPED_ORDER_BY: Self = Self(84);
253    pub const SQL_FEATURE_SHOW_COLUMNS_MODIFIERS: Self = Self(85);
254    pub const SQL_FEATURE_SHOW_ENTITIES_MODIFIERS: Self = Self(86);
255    pub const SQL_FEATURE_SHOW_INDEXES_MODIFIERS: Self = Self(87);
256    pub const SQL_FEATURE_SHOW_MEMORY_MODIFIERS: Self = Self(88);
257    pub const SQL_FEATURE_SHOW_STORES_MODIFIERS: Self = Self(89);
258    pub const SQL_FEATURE_SHOW_UNSUPPORTED_COMMAND: Self = Self(90);
259    pub const SQL_FEATURE_SIMPLE_CASE_EXPRESSION: Self = Self(91);
260    pub const SQL_FEATURE_STANDALONE_LITERAL_PROJECTION_ITEM: Self = Self(92);
261    pub const SQL_FEATURE_SUPPORTED_GROUPED_ORDER_BY_EXPRESSION_FAMILY: Self = Self(93);
262    pub const SQL_FEATURE_SUPPORTED_ORDER_BY_EXPRESSION_FAMILY: Self = Self(94);
263    pub const SQL_FEATURE_UNION_INTERSECT_EXCEPT: Self = Self(95);
264    pub const SQL_FEATURE_UNSUPPORTED_FUNCTION_NAMESPACE: Self = Self(96);
265    pub const SQL_FEATURE_UPDATE: Self = Self(97);
266    pub const SQL_FEATURE_UPPER_FIELD_PREDICATE_UNSUPPORTED: Self = Self(98);
267    pub const SQL_FEATURE_WINDOW_FUNCTION: Self = Self(99);
268    pub const SQL_FEATURE_WITH: Self = Self(100);
269    pub const SQL_FEATURE_NUMERIC_SCALE_FUNCTION_ARGUMENTS: Self = Self(101);
270    pub const SQL_FEATURE_ORDER_BY_FIELD_NOT_ORDERABLE: Self = Self(102);
271
272    const SQL_FEATURE_DETAILS: [SqlFeatureCode; 65] = [
273        SqlFeatureCode::AggregateFilterClause,
274        SqlFeatureCode::AlterStatementBeyondAlterTable,
275        SqlFeatureCode::AlterTableAddColumnDuplicateDefault,
276        SqlFeatureCode::AlterTableAddColumnModifiers,
277        SqlFeatureCode::AlterTableAddStatementBeyondAddColumn,
278        SqlFeatureCode::AlterTableAlterColumnDropUnsupportedAction,
279        SqlFeatureCode::AlterTableAlterColumnModifiers,
280        SqlFeatureCode::AlterTableAlterColumnSetUnsupportedAction,
281        SqlFeatureCode::AlterTableAlterColumnUnsupportedAction,
282        SqlFeatureCode::AlterTableAlterStatementBeyondAlterColumn,
283        SqlFeatureCode::AlterTableDropColumnIfExistsSyntax,
284        SqlFeatureCode::AlterTableDropColumnModifiers,
285        SqlFeatureCode::AlterTableDropStatementBeyondDropColumn,
286        SqlFeatureCode::AlterTableRenameColumnMissingTo,
287        SqlFeatureCode::AlterTableRenameColumnModifiers,
288        SqlFeatureCode::AlterTableRenameStatementBeyondRenameColumn,
289        SqlFeatureCode::AlterTableUnsupportedOperation,
290        SqlFeatureCode::ColumnAlias,
291        SqlFeatureCode::CreateIndexIfNotExistsSyntax,
292        SqlFeatureCode::CreateIndexKeyOrderingModifiers,
293        SqlFeatureCode::CreateIndexModifiers,
294        SqlFeatureCode::CreateStatementBeyondCreateIndex,
295        SqlFeatureCode::DescribeModifier,
296        SqlFeatureCode::DdlSchemaVersionDuplicateExpectedClause,
297        SqlFeatureCode::DdlSchemaVersionDuplicateSetClause,
298        SqlFeatureCode::DropIndexModifiers,
299        SqlFeatureCode::DropIndexIfExistsSyntax,
300        SqlFeatureCode::DropStatementBeyondDropIndex,
301        SqlFeatureCode::ExpressionIndexUnsupportedFunction,
302        SqlFeatureCode::Having,
303        SqlFeatureCode::Insert,
304        SqlFeatureCode::Join,
305        SqlFeatureCode::LikePatternBeyondTrailingPrefix,
306        SqlFeatureCode::LowerFieldPredicateUnsupported,
307        SqlFeatureCode::MultiStatementSql,
308        SqlFeatureCode::NestedAggregateInput,
309        SqlFeatureCode::NestedProjectionFunctionInArithmetic,
310        SqlFeatureCode::OrderByUnsupportedForm,
311        SqlFeatureCode::Other,
312        SqlFeatureCode::ParameterBinding,
313        SqlFeatureCode::ParameterizedSchemaVersion,
314        SqlFeatureCode::PredicateStartsWithFirstArgument,
315        SqlFeatureCode::QuotedIdentifiers,
316        SqlFeatureCode::ReturningUnsupportedShape,
317        SqlFeatureCode::ScalarFunctionExpressionPosition,
318        SqlFeatureCode::ScaleTakingNumericFunctionExpressionPosition,
319        SqlFeatureCode::SearchedCaseGroupedOrderBy,
320        SqlFeatureCode::ShowColumnsModifiers,
321        SqlFeatureCode::ShowEntitiesModifiers,
322        SqlFeatureCode::ShowIndexesModifiers,
323        SqlFeatureCode::ShowMemoryModifiers,
324        SqlFeatureCode::ShowStoresModifiers,
325        SqlFeatureCode::ShowUnsupportedCommand,
326        SqlFeatureCode::SimpleCaseExpression,
327        SqlFeatureCode::StandaloneLiteralProjectionItem,
328        SqlFeatureCode::SupportedGroupedOrderByExpressionFamily,
329        SqlFeatureCode::SupportedOrderByExpressionFamily,
330        SqlFeatureCode::UnionIntersectExcept,
331        SqlFeatureCode::UnsupportedFunctionNamespace,
332        SqlFeatureCode::Update,
333        SqlFeatureCode::UpperFieldPredicateUnsupported,
334        SqlFeatureCode::WindowFunction,
335        SqlFeatureCode::With,
336        SqlFeatureCode::NumericScaleFunctionArguments,
337        SqlFeatureCode::OrderByFieldNotOrderable,
338    ];
339
340    pub const SQL_SURFACE_QUERY_REJECTS_INSERT: Self = Self(103);
341    pub const SQL_SURFACE_QUERY_REJECTS_UPDATE: Self = Self(104);
342    pub const SQL_SURFACE_QUERY_REJECTS_DELETE: Self = Self(105);
343    pub const SQL_SURFACE_UPDATE_REJECTS_SELECT: Self = Self(106);
344    pub const SQL_SURFACE_UPDATE_REJECTS_EXPLAIN: Self = Self(107);
345    pub const SQL_SURFACE_UPDATE_REJECTS_DESCRIBE: Self = Self(108);
346    pub const SQL_SURFACE_UPDATE_REJECTS_SHOW_INDEXES: Self = Self(109);
347    pub const SQL_SURFACE_UPDATE_REJECTS_SHOW_COLUMNS: Self = Self(110);
348    pub const SQL_SURFACE_UPDATE_REJECTS_SHOW_ENTITIES: Self = Self(111);
349    pub const SQL_SURFACE_UPDATE_REJECTS_SHOW_STORES: Self = Self(112);
350    pub const SQL_SURFACE_UPDATE_REJECTS_SHOW_MEMORY: Self = Self(113);
351
352    pub const SCHEMA_DDL_MISSING_EXPECTED_SCHEMA_VERSION: Self = Self(114);
353    pub const SCHEMA_DDL_MISSING_NEXT_SCHEMA_VERSION: Self = Self(115);
354    pub const SCHEMA_DDL_STALE_EXPECTED_SCHEMA_VERSION: Self = Self(116);
355    pub const SCHEMA_DDL_INVALID_EXPECTED_SCHEMA_VERSION: Self = Self(117);
356    pub const SCHEMA_DDL_INVALID_NEXT_SCHEMA_VERSION: Self = Self(118);
357    pub const SCHEMA_DDL_ACCEPTED_SCHEMA_CHANGE_WITHOUT_VERSION_BUMP: Self = Self(119);
358    pub const SCHEMA_DDL_EMPTY_VERSION_BUMP: Self = Self(120);
359    pub const SCHEMA_DDL_VERSION_GAP: Self = Self(121);
360    pub const SCHEMA_DDL_VERSION_ROLLBACK: Self = Self(122);
361    pub const SCHEMA_DDL_FINGERPRINT_METHOD_MISMATCH: Self = Self(123);
362    pub const SCHEMA_DDL_UNSUPPORTED_TRANSITION_CLASS: Self = Self(124);
363    pub const SCHEMA_DDL_PHYSICAL_RUNNER_MISSING: Self = Self(125);
364    pub const SCHEMA_DDL_VALIDATION_FAILED: Self = Self(126);
365    pub const SCHEMA_DDL_PUBLICATION_RACE_LOST: Self = Self(127);
366    pub const SCHEMA_DDL_INVALID_ADD_COLUMN_DEFAULT: Self = Self(128);
367    pub const SCHEMA_DDL_INVALID_ALTER_COLUMN_DEFAULT: Self = Self(129);
368    pub const SCHEMA_DDL_GENERATED_INDEX_DROP_REJECTED: Self = Self(130);
369    pub const SCHEMA_DDL_REQUIRED_DROP_DEFAULT_UNSUPPORTED: Self = Self(131);
370    pub const SCHEMA_DDL_GENERATED_FIELD_DEFAULT_CHANGE_REJECTED: Self = Self(132);
371    pub const SCHEMA_DDL_GENERATED_FIELD_NULLABILITY_CHANGE_REJECTED: Self = Self(133);
372    pub const SCHEMA_DDL_SET_NOT_NULL_VALIDATION_FAILED: Self = Self(134);
373    pub const QUERY_SQL_WRITE_BOUNDARY: Self = Self(135);
374    pub const SQL_WRITE_PRIMARY_KEY_LITERAL_SHAPE: Self = Self(136);
375    pub const SQL_WRITE_PRIMARY_KEY_LITERAL_INCOMPATIBLE: Self = Self(137);
376    pub const SQL_WRITE_MISSING_PRIMARY_KEY: Self = Self(138);
377    pub const SQL_WRITE_MISSING_REQUIRED_FIELDS: Self = Self(139);
378    pub const SQL_WRITE_EXPLICIT_MANAGED_FIELD: Self = Self(140);
379    pub const SQL_WRITE_EXPLICIT_GENERATED_FIELD: Self = Self(141);
380    pub const SQL_WRITE_INSERT_SELECT_REQUIRES_SCALAR: Self = Self(142);
381    pub const SQL_WRITE_INSERT_SELECT_AGGREGATE_PROJECTION: Self = Self(143);
382    pub const SQL_WRITE_INSERT_SELECT_WIDTH_MISMATCH: Self = Self(144);
383    pub const SQL_WRITE_UPDATE_PRIMARY_KEY_MUTATION: Self = Self(145);
384    pub const SQL_WRITE_INVALID_FIELD_LITERAL: Self = Self(146);
385    pub const SQL_WRITE_UNKNOWN_RETURNING_FIELD: Self = Self(147);
386    pub const SQL_WRITE_DUPLICATE_RETURNING_FIELD: Self = Self(148);
387    pub const SQL_WRITE_UPDATE_MISSING_WHERE_PREDICATE: Self = Self(149);
388    pub const SQL_WRITE_ORDER_BY_UNSUPPORTED_SHAPE: Self = Self(150);
389    pub const QUERY_UNSUPPORTED_PROJECTION: Self = Self(151);
390    pub const QUERY_PROJECTION_NUMERIC_LITERAL_REQUIRED: Self = Self(152);
391    pub const QUERY_PROJECTION_NUMERIC_SCALE_ARGUMENTS: Self = Self(153);
392    pub const QUERY_PROJECTION_NESTED_FIELD_PATH_PREVIEW: Self = Self(154);
393    pub const QUERY_PROJECTION_CASE_CONDITION_BOOLEAN_REQUIRED: Self = Self(155);
394    pub const QUERY_PROJECTION_NUMERIC_INPUT_REQUIRED: Self = Self(156);
395    pub const QUERY_PROJECTION_TEXT_OR_BLOB_INPUT_REQUIRED: Self = Self(157);
396    pub const QUERY_PROJECTION_TEXT_INPUT_REQUIRED: Self = Self(158);
397    pub const QUERY_PROJECTION_TEXT_OR_NULL_ARGUMENT_REQUIRED: Self = Self(159);
398    pub const QUERY_PROJECTION_INTEGER_OR_NULL_ARGUMENT_REQUIRED: Self = Self(160);
399    pub const QUERY_PROJECTION_UNARY_OPERAND_INCOMPATIBLE: Self = Self(161);
400    pub const QUERY_PROJECTION_BINARY_OPERANDS_INCOMPATIBLE: Self = Self(162);
401    pub const QUERY_RESULT_SHAPE_MISMATCH: Self = Self(163);
402    pub const QUERY_RESULT_EXPECTED_ROWS: Self = Self(164);
403    pub const QUERY_RESULT_EXPECTED_GROUPED: Self = Self(165);
404    pub const SQL_LOWERING_ENTITY_MISMATCH: Self = Self(166);
405    pub const SQL_LOWERING_SELECT_PROJECTION_SHAPE: Self = Self(167);
406    pub const SQL_LOWERING_SELECT_DISTINCT: Self = Self(168);
407    pub const SQL_LOWERING_DISTINCT_ORDER_BY_PROJECTION: Self = Self(169);
408    pub const SQL_LOWERING_GLOBAL_AGGREGATE_PROJECTION: Self = Self(170);
409    pub const SQL_LOWERING_GLOBAL_AGGREGATE_GROUP_BY: Self = Self(171);
410    pub const SQL_LOWERING_SELECT_GROUP_BY_SHAPE: Self = Self(172);
411    pub const SQL_LOWERING_GROUPED_PROJECTION_EXPLICIT_LIST_REQUIRED: Self = Self(173);
412    pub const SQL_LOWERING_GROUPED_PROJECTION_AGGREGATE_REQUIRED: Self = Self(174);
413    pub const SQL_LOWERING_GROUPED_PROJECTION_NON_GROUP_FIELD: Self = Self(175);
414    pub const SQL_LOWERING_GROUPED_PROJECTION_SCALAR_AFTER_AGGREGATE: Self = Self(176);
415    pub const SQL_LOWERING_HAVING_REQUIRES_GROUP_BY: Self = Self(177);
416    pub const SQL_LOWERING_SELECT_HAVING_SHAPE: Self = Self(178);
417    pub const SQL_LOWERING_AGGREGATE_INPUT_EXPRESSIONS: Self = Self(179);
418    pub const SQL_LOWERING_WHERE_EXPRESSION_SHAPE: Self = Self(180);
419    pub const SQL_LOWERING_PARAMETER_PLACEMENT: Self = Self(181);
420    pub const SQL_LOWERING_SQL_DDL_EXECUTION_UNSUPPORTED: Self = Self(182);
421
422    /// Build an error code from its raw public wire value.
423    #[must_use]
424    pub const fn from_raw(raw: u16) -> Self {
425        Self(raw)
426    }
427
428    /// Return the raw public wire value.
429    #[must_use]
430    pub const fn raw(self) -> u16 {
431        self.0
432    }
433
434    /// Collapse a rich diagnostic into one public leaf code.
435    #[must_use]
436    pub const fn from_parts(code: DiagnosticCode, detail: Option<DiagnosticDetail>) -> Self {
437        match detail {
438            Some(DiagnosticDetail::QueryKind { kind }) => Self::from_query_kind(kind),
439            Some(DiagnosticDetail::RuntimeKind { kind }) => Self::from_runtime_kind(kind),
440            Some(DiagnosticDetail::RuntimeBoundary { boundary }) => {
441                Self::from_runtime_boundary(boundary)
442            }
443            Some(DiagnosticDetail::SchemaDdlAdmission { reason }) => Self::from_schema_ddl(reason),
444            Some(DiagnosticDetail::UnsupportedSqlFeature { feature }) => {
445                Self::from_sql_feature(feature)
446            }
447            Some(DiagnosticDetail::SqlSurfaceMismatch { mismatch }) => {
448                Self::from_sql_surface_mismatch(mismatch)
449            }
450            Some(DiagnosticDetail::SqlWriteBoundary { boundary }) => {
451                Self::from_sql_write_boundary(boundary)
452            }
453            Some(DiagnosticDetail::QueryProjection { reason }) => {
454                Self::from_query_projection(reason)
455            }
456            Some(DiagnosticDetail::QueryResultShape { reason }) => {
457                Self::from_query_result_shape(reason)
458            }
459            Some(DiagnosticDetail::SqlLowering { reason }) => Self::from_sql_lowering(reason),
460            None => code.error_code(),
461        }
462    }
463
464    /// Return the broad diagnostic reason represented by this public code.
465    #[must_use]
466    pub const fn diagnostic_code(self) -> DiagnosticCode {
467        match self.raw() {
468            1 => DiagnosticCode::QueryValidate,
469            2 => DiagnosticCode::QueryIntent,
470            3 => DiagnosticCode::QueryPlan,
471            4 => DiagnosticCode::QueryAccessRequirement,
472            5 => DiagnosticCode::QueryUnorderedPagination,
473            6 => DiagnosticCode::QueryInvalidContinuationCursor,
474            7 => DiagnosticCode::QueryNotFound,
475            8 => DiagnosticCode::QueryNotUnique,
476            9 => DiagnosticCode::QueryNumericOverflow,
477            10 => DiagnosticCode::QueryNumericNotRepresentable,
478            11 => DiagnosticCode::QueryUnknownAggregateTargetField,
479            151..=162 => DiagnosticCode::QueryUnsupportedProjection,
480            163..=165 => DiagnosticCode::QueryResultShapeMismatch,
481            12 | 38..=102 | 166..=182 => DiagnosticCode::QueryUnsupportedSqlFeature,
482            13 | 103..=113 => DiagnosticCode::QuerySqlSurfaceMismatch,
483            14 | 114..=134 => DiagnosticCode::SchemaDdlAdmission,
484            135..=150 => DiagnosticCode::QuerySqlWriteBoundary,
485            15 => DiagnosticCode::StoreNotFound,
486            16 => DiagnosticCode::StoreCorruption,
487            17 => DiagnosticCode::StoreInvariantViolation,
488            18 => DiagnosticCode::RuntimeCorruption,
489            19 => DiagnosticCode::RuntimeIncompatiblePersistedFormat,
490            20 => DiagnosticCode::RuntimeInvariantViolation,
491            21 => DiagnosticCode::RuntimeConflict,
492            22 => DiagnosticCode::RuntimeNotFound,
493            23 | 25..=37 => DiagnosticCode::RuntimeUnsupported,
494            _ => DiagnosticCode::RuntimeInternal,
495        }
496    }
497
498    /// Return the diagnostic class represented by this public code.
499    #[must_use]
500    pub const fn class(self) -> ErrorClass {
501        self.diagnostic_code().class()
502    }
503
504    /// Reconstruct rich diagnostic detail for host-side rendering, when known.
505    #[must_use]
506    pub const fn diagnostic_detail(self) -> Option<DiagnosticDetail> {
507        match self.raw() {
508            1..=8 => Self::query_kind_detail(self.raw()),
509            18..=24 => Self::runtime_kind_detail(self.raw()),
510            25..=37 => Self::runtime_boundary_detail(self.raw()),
511            38..=102 => Self::sql_feature_detail(self.raw()),
512            103..=113 => Self::sql_surface_detail(self.raw()),
513            114..=134 => Self::schema_ddl_detail(self.raw()),
514            136..=150 => Self::sql_write_boundary_detail(self.raw()),
515            152..=162 => Self::query_projection_detail(self.raw()),
516            164..=165 => Self::query_result_shape_detail(self.raw()),
517            166..=182 => Self::sql_lowering_detail(self.raw()),
518            _ => None,
519        }
520    }
521
522    /// Reconstruct a rich diagnostic payload for host-side rendering.
523    #[must_use]
524    pub const fn diagnostic(self, origin: ErrorOrigin) -> Diagnostic {
525        Diagnostic::new(self.diagnostic_code(), origin, self.diagnostic_detail())
526    }
527
528    const fn from_query_kind(kind: QueryErrorKind) -> Self {
529        match kind {
530            QueryErrorKind::Validate => Self::QUERY_VALIDATE,
531            QueryErrorKind::Intent => Self::QUERY_INTENT,
532            QueryErrorKind::Plan => Self::QUERY_PLAN,
533            QueryErrorKind::AccessRequirement => Self::QUERY_ACCESS_REQUIREMENT,
534            QueryErrorKind::UnorderedPagination => Self::QUERY_UNORDERED_PAGINATION,
535            QueryErrorKind::InvalidContinuationCursor => Self::QUERY_INVALID_CONTINUATION_CURSOR,
536            QueryErrorKind::NotFound => Self::QUERY_NOT_FOUND,
537            QueryErrorKind::NotUnique => Self::QUERY_NOT_UNIQUE,
538        }
539    }
540
541    const fn from_runtime_kind(kind: RuntimeErrorKind) -> Self {
542        match kind {
543            RuntimeErrorKind::Corruption => Self::RUNTIME_CORRUPTION,
544            RuntimeErrorKind::IncompatiblePersistedFormat => {
545                Self::RUNTIME_INCOMPATIBLE_PERSISTED_FORMAT
546            }
547            RuntimeErrorKind::InvariantViolation => Self::RUNTIME_INVARIANT_VIOLATION,
548            RuntimeErrorKind::Conflict => Self::RUNTIME_CONFLICT,
549            RuntimeErrorKind::NotFound => Self::RUNTIME_NOT_FOUND,
550            RuntimeErrorKind::Unsupported => Self::RUNTIME_UNSUPPORTED,
551            RuntimeErrorKind::Internal => Self::RUNTIME_INTERNAL,
552        }
553    }
554
555    const fn from_runtime_boundary(boundary: RuntimeBoundaryCode) -> Self {
556        Self(Self::RUNTIME_BOUNDARY_SQL_SURFACE_CONTROLLER_REQUIRED.raw() + boundary as u16)
557    }
558
559    const fn from_sql_feature(feature: SqlFeatureCode) -> Self {
560        Self(Self::SQL_FEATURE_AGGREGATE_FILTER_CLAUSE.raw() + feature as u16)
561    }
562
563    const fn from_sql_surface_mismatch(mismatch: SqlSurfaceMismatchCode) -> Self {
564        Self(Self::SQL_SURFACE_QUERY_REJECTS_INSERT.raw() + mismatch as u16)
565    }
566
567    const fn from_schema_ddl(reason: SchemaDdlAdmissionCode) -> Self {
568        Self(Self::SCHEMA_DDL_MISSING_EXPECTED_SCHEMA_VERSION.raw() + reason as u16)
569    }
570
571    const fn from_sql_write_boundary(boundary: SqlWriteBoundaryCode) -> Self {
572        Self(Self::SQL_WRITE_PRIMARY_KEY_LITERAL_SHAPE.raw() + boundary as u16)
573    }
574
575    const fn from_query_projection(reason: QueryProjectionCode) -> Self {
576        Self(Self::QUERY_PROJECTION_NUMERIC_LITERAL_REQUIRED.raw() + reason as u16)
577    }
578
579    const fn from_query_result_shape(reason: QueryResultShapeCode) -> Self {
580        Self(Self::QUERY_RESULT_EXPECTED_ROWS.raw() + reason as u16)
581    }
582
583    const fn from_sql_lowering(reason: SqlLoweringCode) -> Self {
584        Self(Self::SQL_LOWERING_ENTITY_MISMATCH.raw() + reason as u16)
585    }
586
587    const fn query_kind_detail(raw: u16) -> Option<DiagnosticDetail> {
588        match raw {
589            1 => Some(DiagnosticDetail::QueryKind {
590                kind: QueryErrorKind::Validate,
591            }),
592            2 => Some(DiagnosticDetail::QueryKind {
593                kind: QueryErrorKind::Intent,
594            }),
595            3 => Some(DiagnosticDetail::QueryKind {
596                kind: QueryErrorKind::Plan,
597            }),
598            4 => Some(DiagnosticDetail::QueryKind {
599                kind: QueryErrorKind::AccessRequirement,
600            }),
601            5 => Some(DiagnosticDetail::QueryKind {
602                kind: QueryErrorKind::UnorderedPagination,
603            }),
604            6 => Some(DiagnosticDetail::QueryKind {
605                kind: QueryErrorKind::InvalidContinuationCursor,
606            }),
607            7 => Some(DiagnosticDetail::QueryKind {
608                kind: QueryErrorKind::NotFound,
609            }),
610            8 => Some(DiagnosticDetail::QueryKind {
611                kind: QueryErrorKind::NotUnique,
612            }),
613            _ => None,
614        }
615    }
616
617    const fn runtime_kind_detail(raw: u16) -> Option<DiagnosticDetail> {
618        match raw {
619            18 => Some(DiagnosticDetail::RuntimeKind {
620                kind: RuntimeErrorKind::Corruption,
621            }),
622            19 => Some(DiagnosticDetail::RuntimeKind {
623                kind: RuntimeErrorKind::IncompatiblePersistedFormat,
624            }),
625            20 => Some(DiagnosticDetail::RuntimeKind {
626                kind: RuntimeErrorKind::InvariantViolation,
627            }),
628            21 => Some(DiagnosticDetail::RuntimeKind {
629                kind: RuntimeErrorKind::Conflict,
630            }),
631            22 => Some(DiagnosticDetail::RuntimeKind {
632                kind: RuntimeErrorKind::NotFound,
633            }),
634            23 => Some(DiagnosticDetail::RuntimeKind {
635                kind: RuntimeErrorKind::Unsupported,
636            }),
637            24 => Some(DiagnosticDetail::RuntimeKind {
638                kind: RuntimeErrorKind::Internal,
639            }),
640            _ => None,
641        }
642    }
643
644    const fn runtime_boundary_detail(raw: u16) -> Option<DiagnosticDetail> {
645        match raw {
646            25 => Some(DiagnosticDetail::RuntimeBoundary {
647                boundary: RuntimeBoundaryCode::SqlSurfaceControllerRequired,
648            }),
649            26 => Some(DiagnosticDetail::RuntimeBoundary {
650                boundary: RuntimeBoundaryCode::SchemaSurfaceControllerRequired,
651            }),
652            27 => Some(DiagnosticDetail::RuntimeBoundary {
653                boundary: RuntimeBoundaryCode::SqlQueryNoConfiguredEntities,
654            }),
655            28 => Some(DiagnosticDetail::RuntimeBoundary {
656                boundary: RuntimeBoundaryCode::SqlQueryEntityNotConfigured,
657            }),
658            29 => Some(DiagnosticDetail::RuntimeBoundary {
659                boundary: RuntimeBoundaryCode::SqlDdlTargetRequired,
660            }),
661            30 => Some(DiagnosticDetail::RuntimeBoundary {
662                boundary: RuntimeBoundaryCode::SqlDdlEntityNotConfigured,
663            }),
664            31 => Some(DiagnosticDetail::RuntimeBoundary {
665                boundary: RuntimeBoundaryCode::QueryResponseRowsRequired,
666            }),
667            32 => Some(DiagnosticDetail::RuntimeBoundary {
668                boundary: RuntimeBoundaryCode::QueryResponseGroupedRowsRequired,
669            }),
670            33 => Some(DiagnosticDetail::RuntimeBoundary {
671                boundary: RuntimeBoundaryCode::MutationResultEntityRequired,
672            }),
673            34 => Some(DiagnosticDetail::RuntimeBoundary {
674                boundary: RuntimeBoundaryCode::MutationResultEntitiesRequired,
675            }),
676            35 => Some(DiagnosticDetail::RuntimeBoundary {
677                boundary: RuntimeBoundaryCode::MutationResultIdRequired,
678            }),
679            36 => Some(DiagnosticDetail::RuntimeBoundary {
680                boundary: RuntimeBoundaryCode::MutationResultIdsRequired,
681            }),
682            37 => Some(DiagnosticDetail::RuntimeBoundary {
683                boundary: RuntimeBoundaryCode::RowProjectionFieldNotConfigured,
684            }),
685            _ => None,
686        }
687    }
688
689    const fn sql_feature_detail(raw: u16) -> Option<DiagnosticDetail> {
690        let base = Self::SQL_FEATURE_AGGREGATE_FILTER_CLAUSE.raw();
691        if raw < base {
692            return None;
693        }
694
695        let offset = (raw - base) as usize;
696        if offset < Self::SQL_FEATURE_DETAILS.len() {
697            Some(DiagnosticDetail::UnsupportedSqlFeature {
698                feature: Self::SQL_FEATURE_DETAILS[offset],
699            })
700        } else {
701            None
702        }
703    }
704
705    const fn sql_surface_detail(raw: u16) -> Option<DiagnosticDetail> {
706        match raw {
707            103 => Some(DiagnosticDetail::SqlSurfaceMismatch {
708                mismatch: SqlSurfaceMismatchCode::QueryRejectsInsert,
709            }),
710            104 => Some(DiagnosticDetail::SqlSurfaceMismatch {
711                mismatch: SqlSurfaceMismatchCode::QueryRejectsUpdate,
712            }),
713            105 => Some(DiagnosticDetail::SqlSurfaceMismatch {
714                mismatch: SqlSurfaceMismatchCode::QueryRejectsDelete,
715            }),
716            106 => Some(DiagnosticDetail::SqlSurfaceMismatch {
717                mismatch: SqlSurfaceMismatchCode::UpdateRejectsSelect,
718            }),
719            107 => Some(DiagnosticDetail::SqlSurfaceMismatch {
720                mismatch: SqlSurfaceMismatchCode::UpdateRejectsExplain,
721            }),
722            108 => Some(DiagnosticDetail::SqlSurfaceMismatch {
723                mismatch: SqlSurfaceMismatchCode::UpdateRejectsDescribe,
724            }),
725            109 => Some(DiagnosticDetail::SqlSurfaceMismatch {
726                mismatch: SqlSurfaceMismatchCode::UpdateRejectsShowIndexes,
727            }),
728            110 => Some(DiagnosticDetail::SqlSurfaceMismatch {
729                mismatch: SqlSurfaceMismatchCode::UpdateRejectsShowColumns,
730            }),
731            111 => Some(DiagnosticDetail::SqlSurfaceMismatch {
732                mismatch: SqlSurfaceMismatchCode::UpdateRejectsShowEntities,
733            }),
734            112 => Some(DiagnosticDetail::SqlSurfaceMismatch {
735                mismatch: SqlSurfaceMismatchCode::UpdateRejectsShowStores,
736            }),
737            113 => Some(DiagnosticDetail::SqlSurfaceMismatch {
738                mismatch: SqlSurfaceMismatchCode::UpdateRejectsShowMemory,
739            }),
740            _ => None,
741        }
742    }
743
744    const fn schema_ddl_detail(raw: u16) -> Option<DiagnosticDetail> {
745        match raw {
746            114 => Some(DiagnosticDetail::SchemaDdlAdmission {
747                reason: SchemaDdlAdmissionCode::MissingExpectedSchemaVersion,
748            }),
749            115 => Some(DiagnosticDetail::SchemaDdlAdmission {
750                reason: SchemaDdlAdmissionCode::MissingNextSchemaVersion,
751            }),
752            116 => Some(DiagnosticDetail::SchemaDdlAdmission {
753                reason: SchemaDdlAdmissionCode::StaleExpectedSchemaVersion,
754            }),
755            117 => Some(DiagnosticDetail::SchemaDdlAdmission {
756                reason: SchemaDdlAdmissionCode::InvalidExpectedSchemaVersion,
757            }),
758            118 => Some(DiagnosticDetail::SchemaDdlAdmission {
759                reason: SchemaDdlAdmissionCode::InvalidNextSchemaVersion,
760            }),
761            119 => Some(DiagnosticDetail::SchemaDdlAdmission {
762                reason: SchemaDdlAdmissionCode::AcceptedSchemaChangeWithoutVersionBump,
763            }),
764            120 => Some(DiagnosticDetail::SchemaDdlAdmission {
765                reason: SchemaDdlAdmissionCode::EmptyVersionBump,
766            }),
767            121 => Some(DiagnosticDetail::SchemaDdlAdmission {
768                reason: SchemaDdlAdmissionCode::VersionGap,
769            }),
770            122 => Some(DiagnosticDetail::SchemaDdlAdmission {
771                reason: SchemaDdlAdmissionCode::VersionRollback,
772            }),
773            123 => Some(DiagnosticDetail::SchemaDdlAdmission {
774                reason: SchemaDdlAdmissionCode::FingerprintMethodMismatch,
775            }),
776            124 => Some(DiagnosticDetail::SchemaDdlAdmission {
777                reason: SchemaDdlAdmissionCode::UnsupportedTransitionClass,
778            }),
779            125 => Some(DiagnosticDetail::SchemaDdlAdmission {
780                reason: SchemaDdlAdmissionCode::PhysicalRunnerMissing,
781            }),
782            126 => Some(DiagnosticDetail::SchemaDdlAdmission {
783                reason: SchemaDdlAdmissionCode::ValidationFailed,
784            }),
785            127 => Some(DiagnosticDetail::SchemaDdlAdmission {
786                reason: SchemaDdlAdmissionCode::PublicationRaceLost,
787            }),
788            128 => Some(DiagnosticDetail::SchemaDdlAdmission {
789                reason: SchemaDdlAdmissionCode::InvalidAddColumnDefault,
790            }),
791            129 => Some(DiagnosticDetail::SchemaDdlAdmission {
792                reason: SchemaDdlAdmissionCode::InvalidAlterColumnDefault,
793            }),
794            130 => Some(DiagnosticDetail::SchemaDdlAdmission {
795                reason: SchemaDdlAdmissionCode::GeneratedIndexDropRejected,
796            }),
797            131 => Some(DiagnosticDetail::SchemaDdlAdmission {
798                reason: SchemaDdlAdmissionCode::RequiredDropDefaultUnsupported,
799            }),
800            132 => Some(DiagnosticDetail::SchemaDdlAdmission {
801                reason: SchemaDdlAdmissionCode::GeneratedFieldDefaultChangeRejected,
802            }),
803            133 => Some(DiagnosticDetail::SchemaDdlAdmission {
804                reason: SchemaDdlAdmissionCode::GeneratedFieldNullabilityChangeRejected,
805            }),
806            134 => Some(DiagnosticDetail::SchemaDdlAdmission {
807                reason: SchemaDdlAdmissionCode::SetNotNullValidationFailed,
808            }),
809            _ => None,
810        }
811    }
812
813    const fn sql_write_boundary_detail(raw: u16) -> Option<DiagnosticDetail> {
814        match raw {
815            136 => Some(DiagnosticDetail::SqlWriteBoundary {
816                boundary: SqlWriteBoundaryCode::PrimaryKeyLiteralShape,
817            }),
818            137 => Some(DiagnosticDetail::SqlWriteBoundary {
819                boundary: SqlWriteBoundaryCode::PrimaryKeyLiteralIncompatible,
820            }),
821            138 => Some(DiagnosticDetail::SqlWriteBoundary {
822                boundary: SqlWriteBoundaryCode::MissingPrimaryKey,
823            }),
824            139 => Some(DiagnosticDetail::SqlWriteBoundary {
825                boundary: SqlWriteBoundaryCode::MissingRequiredFields,
826            }),
827            140 => Some(DiagnosticDetail::SqlWriteBoundary {
828                boundary: SqlWriteBoundaryCode::ExplicitManagedField,
829            }),
830            141 => Some(DiagnosticDetail::SqlWriteBoundary {
831                boundary: SqlWriteBoundaryCode::ExplicitGeneratedField,
832            }),
833            142 => Some(DiagnosticDetail::SqlWriteBoundary {
834                boundary: SqlWriteBoundaryCode::InsertSelectRequiresScalar,
835            }),
836            143 => Some(DiagnosticDetail::SqlWriteBoundary {
837                boundary: SqlWriteBoundaryCode::InsertSelectAggregateProjection,
838            }),
839            144 => Some(DiagnosticDetail::SqlWriteBoundary {
840                boundary: SqlWriteBoundaryCode::InsertSelectWidthMismatch,
841            }),
842            145 => Some(DiagnosticDetail::SqlWriteBoundary {
843                boundary: SqlWriteBoundaryCode::UpdatePrimaryKeyMutation,
844            }),
845            146 => Some(DiagnosticDetail::SqlWriteBoundary {
846                boundary: SqlWriteBoundaryCode::InvalidFieldLiteral,
847            }),
848            147 => Some(DiagnosticDetail::SqlWriteBoundary {
849                boundary: SqlWriteBoundaryCode::UnknownReturningField,
850            }),
851            148 => Some(DiagnosticDetail::SqlWriteBoundary {
852                boundary: SqlWriteBoundaryCode::DuplicateReturningField,
853            }),
854            149 => Some(DiagnosticDetail::SqlWriteBoundary {
855                boundary: SqlWriteBoundaryCode::UpdateMissingWherePredicate,
856            }),
857            150 => Some(DiagnosticDetail::SqlWriteBoundary {
858                boundary: SqlWriteBoundaryCode::WriteOrderByUnsupportedShape,
859            }),
860            _ => None,
861        }
862    }
863
864    const fn query_projection_detail(raw: u16) -> Option<DiagnosticDetail> {
865        match raw {
866            152 => Some(DiagnosticDetail::QueryProjection {
867                reason: QueryProjectionCode::NumericLiteralRequired,
868            }),
869            153 => Some(DiagnosticDetail::QueryProjection {
870                reason: QueryProjectionCode::NumericScaleArguments,
871            }),
872            154 => Some(DiagnosticDetail::QueryProjection {
873                reason: QueryProjectionCode::NestedFieldPathPreview,
874            }),
875            155 => Some(DiagnosticDetail::QueryProjection {
876                reason: QueryProjectionCode::CaseConditionBooleanRequired,
877            }),
878            156 => Some(DiagnosticDetail::QueryProjection {
879                reason: QueryProjectionCode::NumericInputRequired,
880            }),
881            157 => Some(DiagnosticDetail::QueryProjection {
882                reason: QueryProjectionCode::TextOrBlobInputRequired,
883            }),
884            158 => Some(DiagnosticDetail::QueryProjection {
885                reason: QueryProjectionCode::TextInputRequired,
886            }),
887            159 => Some(DiagnosticDetail::QueryProjection {
888                reason: QueryProjectionCode::TextOrNullArgumentRequired,
889            }),
890            160 => Some(DiagnosticDetail::QueryProjection {
891                reason: QueryProjectionCode::IntegerOrNullArgumentRequired,
892            }),
893            161 => Some(DiagnosticDetail::QueryProjection {
894                reason: QueryProjectionCode::UnaryOperandIncompatible,
895            }),
896            162 => Some(DiagnosticDetail::QueryProjection {
897                reason: QueryProjectionCode::BinaryOperandsIncompatible,
898            }),
899            _ => None,
900        }
901    }
902
903    const fn query_result_shape_detail(raw: u16) -> Option<DiagnosticDetail> {
904        match raw {
905            164 => Some(DiagnosticDetail::QueryResultShape {
906                reason: QueryResultShapeCode::ExpectedRows,
907            }),
908            165 => Some(DiagnosticDetail::QueryResultShape {
909                reason: QueryResultShapeCode::ExpectedGroupedRows,
910            }),
911            _ => None,
912        }
913    }
914
915    const fn sql_lowering_detail(raw: u16) -> Option<DiagnosticDetail> {
916        match raw {
917            166 => Some(DiagnosticDetail::SqlLowering {
918                reason: SqlLoweringCode::EntityMismatch,
919            }),
920            167 => Some(DiagnosticDetail::SqlLowering {
921                reason: SqlLoweringCode::SelectProjectionShape,
922            }),
923            168 => Some(DiagnosticDetail::SqlLowering {
924                reason: SqlLoweringCode::SelectDistinct,
925            }),
926            169 => Some(DiagnosticDetail::SqlLowering {
927                reason: SqlLoweringCode::DistinctOrderByProjection,
928            }),
929            170 => Some(DiagnosticDetail::SqlLowering {
930                reason: SqlLoweringCode::GlobalAggregateProjection,
931            }),
932            171 => Some(DiagnosticDetail::SqlLowering {
933                reason: SqlLoweringCode::GlobalAggregateGroupBy,
934            }),
935            172 => Some(DiagnosticDetail::SqlLowering {
936                reason: SqlLoweringCode::SelectGroupByShape,
937            }),
938            173 => Some(DiagnosticDetail::SqlLowering {
939                reason: SqlLoweringCode::GroupedProjectionExplicitListRequired,
940            }),
941            174 => Some(DiagnosticDetail::SqlLowering {
942                reason: SqlLoweringCode::GroupedProjectionAggregateRequired,
943            }),
944            175 => Some(DiagnosticDetail::SqlLowering {
945                reason: SqlLoweringCode::GroupedProjectionNonGroupField,
946            }),
947            176 => Some(DiagnosticDetail::SqlLowering {
948                reason: SqlLoweringCode::GroupedProjectionScalarAfterAggregate,
949            }),
950            177 => Some(DiagnosticDetail::SqlLowering {
951                reason: SqlLoweringCode::HavingRequiresGroupBy,
952            }),
953            178 => Some(DiagnosticDetail::SqlLowering {
954                reason: SqlLoweringCode::SelectHavingShape,
955            }),
956            179 => Some(DiagnosticDetail::SqlLowering {
957                reason: SqlLoweringCode::AggregateInputExpressions,
958            }),
959            180 => Some(DiagnosticDetail::SqlLowering {
960                reason: SqlLoweringCode::WhereExpressionShape,
961            }),
962            181 => Some(DiagnosticDetail::SqlLowering {
963                reason: SqlLoweringCode::ParameterPlacement,
964            }),
965            182 => Some(DiagnosticDetail::SqlLowering {
966                reason: SqlLoweringCode::SqlDdlExecutionUnsupported,
967            }),
968            _ => None,
969        }
970    }
971}
972
973impl std::fmt::Debug for ErrorCode {
974    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
975        f.debug_tuple("ErrorCode").field(&self.0).finish()
976    }
977}
978
979///
980/// ErrorClass
981///
982/// Broad diagnostic class used for recovery decisions.
983///
984
985#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
986pub enum ErrorClass {
987    Query,
988    Corruption,
989    IncompatiblePersistedFormat,
990    NotFound,
991    Internal,
992    Conflict,
993    Unsupported,
994    InvariantViolation,
995}
996
997///
998/// ErrorOrigin
999///
1000/// Subsystem that owns the diagnostic.
1001///
1002
1003#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1004pub enum ErrorOrigin {
1005    Cursor,
1006    Executor,
1007    Identity,
1008    Index,
1009    Interface,
1010    Planner,
1011    Query,
1012    Recovery,
1013    Response,
1014    Runtime,
1015    Serialize,
1016    Store,
1017}
1018
1019///
1020/// QueryErrorKind
1021///
1022/// Public query error category.
1023///
1024
1025#[repr(u16)]
1026#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1027pub enum QueryErrorKind {
1028    Validate,
1029    Intent,
1030    Plan,
1031    AccessRequirement,
1032    UnorderedPagination,
1033    InvalidContinuationCursor,
1034    NotFound,
1035    NotUnique,
1036}
1037
1038///
1039/// QueryProjectionCode
1040///
1041/// Compact query projection admission/runtime identifier.
1042///
1043
1044#[repr(u16)]
1045#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1046pub enum QueryProjectionCode {
1047    NumericLiteralRequired,
1048    NumericScaleArguments,
1049    NestedFieldPathPreview,
1050    CaseConditionBooleanRequired,
1051    NumericInputRequired,
1052    TextOrBlobInputRequired,
1053    TextInputRequired,
1054    TextOrNullArgumentRequired,
1055    IntegerOrNullArgumentRequired,
1056    UnaryOperandIncompatible,
1057    BinaryOperandsIncompatible,
1058}
1059
1060///
1061/// QueryResultShapeCode
1062///
1063/// Compact query-result shape mismatch identifier.
1064///
1065
1066#[repr(u16)]
1067#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1068pub enum QueryResultShapeCode {
1069    ExpectedRows,
1070    ExpectedGroupedRows,
1071}
1072
1073///
1074/// RuntimeErrorKind
1075///
1076/// Public runtime error category.
1077///
1078
1079#[repr(u16)]
1080#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1081pub enum RuntimeErrorKind {
1082    Corruption,
1083    IncompatiblePersistedFormat,
1084    InvariantViolation,
1085    Conflict,
1086    NotFound,
1087    Unsupported,
1088    Internal,
1089}
1090
1091///
1092/// RuntimeBoundaryCode
1093///
1094/// Compact public-runtime boundary identifier.
1095///
1096
1097#[repr(u16)]
1098#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1099pub enum RuntimeBoundaryCode {
1100    SqlSurfaceControllerRequired,
1101    SchemaSurfaceControllerRequired,
1102    SqlQueryNoConfiguredEntities,
1103    SqlQueryEntityNotConfigured,
1104    SqlDdlTargetRequired,
1105    SqlDdlEntityNotConfigured,
1106    QueryResponseRowsRequired,
1107    QueryResponseGroupedRowsRequired,
1108    MutationResultEntityRequired,
1109    MutationResultEntitiesRequired,
1110    MutationResultIdRequired,
1111    MutationResultIdsRequired,
1112    RowProjectionFieldNotConfigured,
1113}
1114
1115///
1116/// SqlFeatureCode
1117///
1118/// Compact SQL feature identifier used by unsupported-feature diagnostics.
1119///
1120
1121#[repr(u16)]
1122#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1123pub enum SqlFeatureCode {
1124    AggregateFilterClause,
1125    AlterStatementBeyondAlterTable,
1126    AlterTableAddColumnDuplicateDefault,
1127    AlterTableAddColumnModifiers,
1128    AlterTableAddStatementBeyondAddColumn,
1129    AlterTableAlterColumnDropUnsupportedAction,
1130    AlterTableAlterColumnModifiers,
1131    AlterTableAlterColumnSetUnsupportedAction,
1132    AlterTableAlterColumnUnsupportedAction,
1133    AlterTableAlterStatementBeyondAlterColumn,
1134    AlterTableDropColumnIfExistsSyntax,
1135    AlterTableDropColumnModifiers,
1136    AlterTableDropStatementBeyondDropColumn,
1137    AlterTableRenameColumnMissingTo,
1138    AlterTableRenameColumnModifiers,
1139    AlterTableRenameStatementBeyondRenameColumn,
1140    AlterTableUnsupportedOperation,
1141    ColumnAlias,
1142    CreateIndexIfNotExistsSyntax,
1143    CreateIndexKeyOrderingModifiers,
1144    CreateIndexModifiers,
1145    CreateStatementBeyondCreateIndex,
1146    DescribeModifier,
1147    DdlSchemaVersionDuplicateExpectedClause,
1148    DdlSchemaVersionDuplicateSetClause,
1149    DropIndexModifiers,
1150    DropIndexIfExistsSyntax,
1151    DropStatementBeyondDropIndex,
1152    ExpressionIndexUnsupportedFunction,
1153    Having,
1154    Insert,
1155    Join,
1156    LikePatternBeyondTrailingPrefix,
1157    LowerFieldPredicateUnsupported,
1158    MultiStatementSql,
1159    NestedAggregateInput,
1160    NestedProjectionFunctionInArithmetic,
1161    OrderByUnsupportedForm,
1162    Other,
1163    ParameterBinding,
1164    ParameterizedSchemaVersion,
1165    PredicateStartsWithFirstArgument,
1166    QuotedIdentifiers,
1167    ReturningUnsupportedShape,
1168    ScalarFunctionExpressionPosition,
1169    ScaleTakingNumericFunctionExpressionPosition,
1170    SearchedCaseGroupedOrderBy,
1171    ShowColumnsModifiers,
1172    ShowEntitiesModifiers,
1173    ShowIndexesModifiers,
1174    ShowMemoryModifiers,
1175    ShowStoresModifiers,
1176    ShowUnsupportedCommand,
1177    SimpleCaseExpression,
1178    StandaloneLiteralProjectionItem,
1179    SupportedGroupedOrderByExpressionFamily,
1180    SupportedOrderByExpressionFamily,
1181    UnionIntersectExcept,
1182    UnsupportedFunctionNamespace,
1183    Update,
1184    UpperFieldPredicateUnsupported,
1185    WindowFunction,
1186    With,
1187    NumericScaleFunctionArguments,
1188    OrderByFieldNotOrderable,
1189}
1190
1191///
1192/// SqlLoweringCode
1193///
1194/// Compact SQL lowering rejection identifier used after parsing succeeds but
1195/// before a statement becomes canonical query intent.
1196///
1197
1198#[repr(u16)]
1199#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1200pub enum SqlLoweringCode {
1201    EntityMismatch,
1202    SelectProjectionShape,
1203    SelectDistinct,
1204    DistinctOrderByProjection,
1205    GlobalAggregateProjection,
1206    GlobalAggregateGroupBy,
1207    SelectGroupByShape,
1208    GroupedProjectionExplicitListRequired,
1209    GroupedProjectionAggregateRequired,
1210    GroupedProjectionNonGroupField,
1211    GroupedProjectionScalarAfterAggregate,
1212    HavingRequiresGroupBy,
1213    SelectHavingShape,
1214    AggregateInputExpressions,
1215    WhereExpressionShape,
1216    ParameterPlacement,
1217    SqlDdlExecutionUnsupported,
1218}
1219
1220///
1221/// SqlSurfaceMismatchCode
1222///
1223/// Compact SQL endpoint surface mismatch identifier.
1224///
1225
1226#[repr(u16)]
1227#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1228pub enum SqlSurfaceMismatchCode {
1229    QueryRejectsInsert,
1230    QueryRejectsUpdate,
1231    QueryRejectsDelete,
1232    UpdateRejectsSelect,
1233    UpdateRejectsExplain,
1234    UpdateRejectsDescribe,
1235    UpdateRejectsShowIndexes,
1236    UpdateRejectsShowColumns,
1237    UpdateRejectsShowEntities,
1238    UpdateRejectsShowStores,
1239    UpdateRejectsShowMemory,
1240}
1241
1242///
1243/// SqlWriteBoundaryCode
1244///
1245/// Compact SQL write fail-closed boundary identifier.
1246///
1247
1248#[repr(u16)]
1249#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1250pub enum SqlWriteBoundaryCode {
1251    PrimaryKeyLiteralShape,
1252    PrimaryKeyLiteralIncompatible,
1253    MissingPrimaryKey,
1254    MissingRequiredFields,
1255    ExplicitManagedField,
1256    ExplicitGeneratedField,
1257    InsertSelectRequiresScalar,
1258    InsertSelectAggregateProjection,
1259    InsertSelectWidthMismatch,
1260    UpdatePrimaryKeyMutation,
1261    InvalidFieldLiteral,
1262    UnknownReturningField,
1263    DuplicateReturningField,
1264    UpdateMissingWherePredicate,
1265    WriteOrderByUnsupportedShape,
1266}
1267
1268///
1269/// SchemaDdlAdmissionCode
1270///
1271/// Compact SQL DDL admission rejection reason.
1272///
1273
1274#[repr(u16)]
1275#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1276pub enum SchemaDdlAdmissionCode {
1277    MissingExpectedSchemaVersion,
1278    MissingNextSchemaVersion,
1279    StaleExpectedSchemaVersion,
1280    InvalidExpectedSchemaVersion,
1281    InvalidNextSchemaVersion,
1282    AcceptedSchemaChangeWithoutVersionBump,
1283    EmptyVersionBump,
1284    VersionGap,
1285    VersionRollback,
1286    FingerprintMethodMismatch,
1287    UnsupportedTransitionClass,
1288    PhysicalRunnerMissing,
1289    ValidationFailed,
1290    PublicationRaceLost,
1291    InvalidAddColumnDefault,
1292    InvalidAlterColumnDefault,
1293    GeneratedIndexDropRejected,
1294    RequiredDropDefaultUnsupported,
1295    GeneratedFieldDefaultChangeRejected,
1296    GeneratedFieldNullabilityChangeRejected,
1297    SetNotNullValidationFailed,
1298}
1299
1300///
1301/// DiagnosticDetail
1302///
1303/// Small structured diagnostic payload for callers and CLI rendering.
1304///
1305
1306#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1307pub enum DiagnosticDetail {
1308    QueryKind { kind: QueryErrorKind },
1309    RuntimeKind { kind: RuntimeErrorKind },
1310    RuntimeBoundary { boundary: RuntimeBoundaryCode },
1311    SchemaDdlAdmission { reason: SchemaDdlAdmissionCode },
1312    UnsupportedSqlFeature { feature: SqlFeatureCode },
1313    SqlSurfaceMismatch { mismatch: SqlSurfaceMismatchCode },
1314    SqlWriteBoundary { boundary: SqlWriteBoundaryCode },
1315    QueryProjection { reason: QueryProjectionCode },
1316    QueryResultShape { reason: QueryResultShapeCode },
1317    SqlLowering { reason: SqlLoweringCode },
1318}
1319
1320///
1321/// Diagnostic
1322///
1323/// Compact public diagnostic payload.
1324///
1325
1326#[derive(Clone, Debug, Eq, PartialEq)]
1327pub struct Diagnostic {
1328    code: DiagnosticCode,
1329    origin: ErrorOrigin,
1330    detail: Option<DiagnosticDetail>,
1331}
1332
1333impl Diagnostic {
1334    /// Build a compact diagnostic from a code and optional structured detail.
1335    #[must_use]
1336    pub const fn new(
1337        code: DiagnosticCode,
1338        origin: ErrorOrigin,
1339        detail: Option<DiagnosticDetail>,
1340    ) -> Self {
1341        Self {
1342            code,
1343            origin,
1344            detail,
1345        }
1346    }
1347
1348    /// Build a compact diagnostic using the code's default origin.
1349    #[must_use]
1350    pub const fn from_code(code: DiagnosticCode) -> Self {
1351        Self::new(code, code.origin(), None)
1352    }
1353
1354    /// Return the stable diagnostic code.
1355    #[must_use]
1356    pub const fn code(&self) -> DiagnosticCode {
1357        self.code
1358    }
1359
1360    /// Return the diagnostic class.
1361    #[must_use]
1362    pub const fn class(&self) -> ErrorClass {
1363        self.code.class()
1364    }
1365
1366    /// Return the subsystem origin.
1367    #[must_use]
1368    pub const fn origin(&self) -> ErrorOrigin {
1369        self.origin
1370    }
1371
1372    /// Return structured diagnostic detail, when available.
1373    #[must_use]
1374    pub const fn detail(&self) -> Option<&DiagnosticDetail> {
1375        self.detail.as_ref()
1376    }
1377
1378    /// Return the numeric public wire code for this diagnostic.
1379    #[must_use]
1380    pub const fn error_code(&self) -> ErrorCode {
1381        ErrorCode::from_parts(self.code, self.detail)
1382    }
1383}
1384
1385#[cfg(test)]
1386mod tests {
1387    use super::{
1388        Diagnostic, DiagnosticCode, DiagnosticDetail, ErrorClass, ErrorCode, ErrorOrigin,
1389        QueryProjectionCode, SqlFeatureCode, SqlLoweringCode,
1390    };
1391
1392    const ORDERED_ERROR_CODES: [ErrorCode; 182] = [
1393        ErrorCode::QUERY_VALIDATE,
1394        ErrorCode::QUERY_INTENT,
1395        ErrorCode::QUERY_PLAN,
1396        ErrorCode::QUERY_ACCESS_REQUIREMENT,
1397        ErrorCode::QUERY_UNORDERED_PAGINATION,
1398        ErrorCode::QUERY_INVALID_CONTINUATION_CURSOR,
1399        ErrorCode::QUERY_NOT_FOUND,
1400        ErrorCode::QUERY_NOT_UNIQUE,
1401        ErrorCode::QUERY_NUMERIC_OVERFLOW,
1402        ErrorCode::QUERY_NUMERIC_NOT_REPRESENTABLE,
1403        ErrorCode::QUERY_UNKNOWN_AGGREGATE_TARGET_FIELD,
1404        ErrorCode::QUERY_UNSUPPORTED_SQL_FEATURE,
1405        ErrorCode::QUERY_SQL_SURFACE_MISMATCH,
1406        ErrorCode::SCHEMA_DDL_ADMISSION,
1407        ErrorCode::STORE_NOT_FOUND,
1408        ErrorCode::STORE_CORRUPTION,
1409        ErrorCode::STORE_INVARIANT_VIOLATION,
1410        ErrorCode::RUNTIME_CORRUPTION,
1411        ErrorCode::RUNTIME_INCOMPATIBLE_PERSISTED_FORMAT,
1412        ErrorCode::RUNTIME_INVARIANT_VIOLATION,
1413        ErrorCode::RUNTIME_CONFLICT,
1414        ErrorCode::RUNTIME_NOT_FOUND,
1415        ErrorCode::RUNTIME_UNSUPPORTED,
1416        ErrorCode::RUNTIME_INTERNAL,
1417        ErrorCode::RUNTIME_BOUNDARY_SQL_SURFACE_CONTROLLER_REQUIRED,
1418        ErrorCode::RUNTIME_BOUNDARY_SCHEMA_SURFACE_CONTROLLER_REQUIRED,
1419        ErrorCode::RUNTIME_BOUNDARY_SQL_QUERY_NO_CONFIGURED_ENTITIES,
1420        ErrorCode::RUNTIME_BOUNDARY_SQL_QUERY_ENTITY_NOT_CONFIGURED,
1421        ErrorCode::RUNTIME_BOUNDARY_SQL_DDL_TARGET_REQUIRED,
1422        ErrorCode::RUNTIME_BOUNDARY_SQL_DDL_ENTITY_NOT_CONFIGURED,
1423        ErrorCode::RUNTIME_BOUNDARY_QUERY_RESPONSE_ROWS_REQUIRED,
1424        ErrorCode::RUNTIME_BOUNDARY_QUERY_RESPONSE_GROUPED_ROWS_REQUIRED,
1425        ErrorCode::RUNTIME_BOUNDARY_MUTATION_RESULT_ENTITY_REQUIRED,
1426        ErrorCode::RUNTIME_BOUNDARY_MUTATION_RESULT_ENTITIES_REQUIRED,
1427        ErrorCode::RUNTIME_BOUNDARY_MUTATION_RESULT_ID_REQUIRED,
1428        ErrorCode::RUNTIME_BOUNDARY_MUTATION_RESULT_IDS_REQUIRED,
1429        ErrorCode::RUNTIME_BOUNDARY_ROW_PROJECTION_FIELD_NOT_CONFIGURED,
1430        ErrorCode::SQL_FEATURE_AGGREGATE_FILTER_CLAUSE,
1431        ErrorCode::SQL_FEATURE_ALTER_STATEMENT_BEYOND_ALTER_TABLE,
1432        ErrorCode::SQL_FEATURE_ALTER_TABLE_ADD_COLUMN_DUPLICATE_DEFAULT,
1433        ErrorCode::SQL_FEATURE_ALTER_TABLE_ADD_COLUMN_MODIFIERS,
1434        ErrorCode::SQL_FEATURE_ALTER_TABLE_ADD_STATEMENT_BEYOND_ADD_COLUMN,
1435        ErrorCode::SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_DROP_UNSUPPORTED_ACTION,
1436        ErrorCode::SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_MODIFIERS,
1437        ErrorCode::SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_SET_UNSUPPORTED_ACTION,
1438        ErrorCode::SQL_FEATURE_ALTER_TABLE_ALTER_COLUMN_UNSUPPORTED_ACTION,
1439        ErrorCode::SQL_FEATURE_ALTER_TABLE_ALTER_STATEMENT_BEYOND_ALTER_COLUMN,
1440        ErrorCode::SQL_FEATURE_ALTER_TABLE_DROP_COLUMN_IF_EXISTS_SYNTAX,
1441        ErrorCode::SQL_FEATURE_ALTER_TABLE_DROP_COLUMN_MODIFIERS,
1442        ErrorCode::SQL_FEATURE_ALTER_TABLE_DROP_STATEMENT_BEYOND_DROP_COLUMN,
1443        ErrorCode::SQL_FEATURE_ALTER_TABLE_RENAME_COLUMN_MISSING_TO,
1444        ErrorCode::SQL_FEATURE_ALTER_TABLE_RENAME_COLUMN_MODIFIERS,
1445        ErrorCode::SQL_FEATURE_ALTER_TABLE_RENAME_STATEMENT_BEYOND_RENAME_COLUMN,
1446        ErrorCode::SQL_FEATURE_ALTER_TABLE_UNSUPPORTED_OPERATION,
1447        ErrorCode::SQL_FEATURE_COLUMN_ALIAS,
1448        ErrorCode::SQL_FEATURE_CREATE_INDEX_IF_NOT_EXISTS_SYNTAX,
1449        ErrorCode::SQL_FEATURE_CREATE_INDEX_KEY_ORDERING_MODIFIERS,
1450        ErrorCode::SQL_FEATURE_CREATE_INDEX_MODIFIERS,
1451        ErrorCode::SQL_FEATURE_CREATE_STATEMENT_BEYOND_CREATE_INDEX,
1452        ErrorCode::SQL_FEATURE_DESCRIBE_MODIFIER,
1453        ErrorCode::SQL_FEATURE_DDL_SCHEMA_VERSION_DUPLICATE_EXPECTED_CLAUSE,
1454        ErrorCode::SQL_FEATURE_DDL_SCHEMA_VERSION_DUPLICATE_SET_CLAUSE,
1455        ErrorCode::SQL_FEATURE_DROP_INDEX_MODIFIERS,
1456        ErrorCode::SQL_FEATURE_DROP_INDEX_IF_EXISTS_SYNTAX,
1457        ErrorCode::SQL_FEATURE_DROP_STATEMENT_BEYOND_DROP_INDEX,
1458        ErrorCode::SQL_FEATURE_EXPRESSION_INDEX_UNSUPPORTED_FUNCTION,
1459        ErrorCode::SQL_FEATURE_HAVING,
1460        ErrorCode::SQL_FEATURE_INSERT,
1461        ErrorCode::SQL_FEATURE_JOIN,
1462        ErrorCode::SQL_FEATURE_LIKE_PATTERN_BEYOND_TRAILING_PREFIX,
1463        ErrorCode::SQL_FEATURE_LOWER_FIELD_PREDICATE_UNSUPPORTED,
1464        ErrorCode::SQL_FEATURE_MULTI_STATEMENT_SQL,
1465        ErrorCode::SQL_FEATURE_NESTED_AGGREGATE_INPUT,
1466        ErrorCode::SQL_FEATURE_NESTED_PROJECTION_FUNCTION_IN_ARITHMETIC,
1467        ErrorCode::SQL_FEATURE_ORDER_BY_UNSUPPORTED_FORM,
1468        ErrorCode::SQL_FEATURE_OTHER,
1469        ErrorCode::SQL_FEATURE_PARAMETER_BINDING,
1470        ErrorCode::SQL_FEATURE_PARAMETERIZED_SCHEMA_VERSION,
1471        ErrorCode::SQL_FEATURE_PREDICATE_STARTS_WITH_FIRST_ARGUMENT,
1472        ErrorCode::SQL_FEATURE_QUOTED_IDENTIFIERS,
1473        ErrorCode::SQL_FEATURE_RETURNING_UNSUPPORTED_SHAPE,
1474        ErrorCode::SQL_FEATURE_SCALAR_FUNCTION_EXPRESSION_POSITION,
1475        ErrorCode::SQL_FEATURE_SCALE_TAKING_NUMERIC_FUNCTION_EXPRESSION_POSITION,
1476        ErrorCode::SQL_FEATURE_SEARCHED_CASE_GROUPED_ORDER_BY,
1477        ErrorCode::SQL_FEATURE_SHOW_COLUMNS_MODIFIERS,
1478        ErrorCode::SQL_FEATURE_SHOW_ENTITIES_MODIFIERS,
1479        ErrorCode::SQL_FEATURE_SHOW_INDEXES_MODIFIERS,
1480        ErrorCode::SQL_FEATURE_SHOW_MEMORY_MODIFIERS,
1481        ErrorCode::SQL_FEATURE_SHOW_STORES_MODIFIERS,
1482        ErrorCode::SQL_FEATURE_SHOW_UNSUPPORTED_COMMAND,
1483        ErrorCode::SQL_FEATURE_SIMPLE_CASE_EXPRESSION,
1484        ErrorCode::SQL_FEATURE_STANDALONE_LITERAL_PROJECTION_ITEM,
1485        ErrorCode::SQL_FEATURE_SUPPORTED_GROUPED_ORDER_BY_EXPRESSION_FAMILY,
1486        ErrorCode::SQL_FEATURE_SUPPORTED_ORDER_BY_EXPRESSION_FAMILY,
1487        ErrorCode::SQL_FEATURE_UNION_INTERSECT_EXCEPT,
1488        ErrorCode::SQL_FEATURE_UNSUPPORTED_FUNCTION_NAMESPACE,
1489        ErrorCode::SQL_FEATURE_UPDATE,
1490        ErrorCode::SQL_FEATURE_UPPER_FIELD_PREDICATE_UNSUPPORTED,
1491        ErrorCode::SQL_FEATURE_WINDOW_FUNCTION,
1492        ErrorCode::SQL_FEATURE_WITH,
1493        ErrorCode::SQL_FEATURE_NUMERIC_SCALE_FUNCTION_ARGUMENTS,
1494        ErrorCode::SQL_FEATURE_ORDER_BY_FIELD_NOT_ORDERABLE,
1495        ErrorCode::SQL_SURFACE_QUERY_REJECTS_INSERT,
1496        ErrorCode::SQL_SURFACE_QUERY_REJECTS_UPDATE,
1497        ErrorCode::SQL_SURFACE_QUERY_REJECTS_DELETE,
1498        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SELECT,
1499        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_EXPLAIN,
1500        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_DESCRIBE,
1501        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SHOW_INDEXES,
1502        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SHOW_COLUMNS,
1503        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SHOW_ENTITIES,
1504        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SHOW_STORES,
1505        ErrorCode::SQL_SURFACE_UPDATE_REJECTS_SHOW_MEMORY,
1506        ErrorCode::SCHEMA_DDL_MISSING_EXPECTED_SCHEMA_VERSION,
1507        ErrorCode::SCHEMA_DDL_MISSING_NEXT_SCHEMA_VERSION,
1508        ErrorCode::SCHEMA_DDL_STALE_EXPECTED_SCHEMA_VERSION,
1509        ErrorCode::SCHEMA_DDL_INVALID_EXPECTED_SCHEMA_VERSION,
1510        ErrorCode::SCHEMA_DDL_INVALID_NEXT_SCHEMA_VERSION,
1511        ErrorCode::SCHEMA_DDL_ACCEPTED_SCHEMA_CHANGE_WITHOUT_VERSION_BUMP,
1512        ErrorCode::SCHEMA_DDL_EMPTY_VERSION_BUMP,
1513        ErrorCode::SCHEMA_DDL_VERSION_GAP,
1514        ErrorCode::SCHEMA_DDL_VERSION_ROLLBACK,
1515        ErrorCode::SCHEMA_DDL_FINGERPRINT_METHOD_MISMATCH,
1516        ErrorCode::SCHEMA_DDL_UNSUPPORTED_TRANSITION_CLASS,
1517        ErrorCode::SCHEMA_DDL_PHYSICAL_RUNNER_MISSING,
1518        ErrorCode::SCHEMA_DDL_VALIDATION_FAILED,
1519        ErrorCode::SCHEMA_DDL_PUBLICATION_RACE_LOST,
1520        ErrorCode::SCHEMA_DDL_INVALID_ADD_COLUMN_DEFAULT,
1521        ErrorCode::SCHEMA_DDL_INVALID_ALTER_COLUMN_DEFAULT,
1522        ErrorCode::SCHEMA_DDL_GENERATED_INDEX_DROP_REJECTED,
1523        ErrorCode::SCHEMA_DDL_REQUIRED_DROP_DEFAULT_UNSUPPORTED,
1524        ErrorCode::SCHEMA_DDL_GENERATED_FIELD_DEFAULT_CHANGE_REJECTED,
1525        ErrorCode::SCHEMA_DDL_GENERATED_FIELD_NULLABILITY_CHANGE_REJECTED,
1526        ErrorCode::SCHEMA_DDL_SET_NOT_NULL_VALIDATION_FAILED,
1527        ErrorCode::QUERY_SQL_WRITE_BOUNDARY,
1528        ErrorCode::SQL_WRITE_PRIMARY_KEY_LITERAL_SHAPE,
1529        ErrorCode::SQL_WRITE_PRIMARY_KEY_LITERAL_INCOMPATIBLE,
1530        ErrorCode::SQL_WRITE_MISSING_PRIMARY_KEY,
1531        ErrorCode::SQL_WRITE_MISSING_REQUIRED_FIELDS,
1532        ErrorCode::SQL_WRITE_EXPLICIT_MANAGED_FIELD,
1533        ErrorCode::SQL_WRITE_EXPLICIT_GENERATED_FIELD,
1534        ErrorCode::SQL_WRITE_INSERT_SELECT_REQUIRES_SCALAR,
1535        ErrorCode::SQL_WRITE_INSERT_SELECT_AGGREGATE_PROJECTION,
1536        ErrorCode::SQL_WRITE_INSERT_SELECT_WIDTH_MISMATCH,
1537        ErrorCode::SQL_WRITE_UPDATE_PRIMARY_KEY_MUTATION,
1538        ErrorCode::SQL_WRITE_INVALID_FIELD_LITERAL,
1539        ErrorCode::SQL_WRITE_UNKNOWN_RETURNING_FIELD,
1540        ErrorCode::SQL_WRITE_DUPLICATE_RETURNING_FIELD,
1541        ErrorCode::SQL_WRITE_UPDATE_MISSING_WHERE_PREDICATE,
1542        ErrorCode::SQL_WRITE_ORDER_BY_UNSUPPORTED_SHAPE,
1543        ErrorCode::QUERY_UNSUPPORTED_PROJECTION,
1544        ErrorCode::QUERY_PROJECTION_NUMERIC_LITERAL_REQUIRED,
1545        ErrorCode::QUERY_PROJECTION_NUMERIC_SCALE_ARGUMENTS,
1546        ErrorCode::QUERY_PROJECTION_NESTED_FIELD_PATH_PREVIEW,
1547        ErrorCode::QUERY_PROJECTION_CASE_CONDITION_BOOLEAN_REQUIRED,
1548        ErrorCode::QUERY_PROJECTION_NUMERIC_INPUT_REQUIRED,
1549        ErrorCode::QUERY_PROJECTION_TEXT_OR_BLOB_INPUT_REQUIRED,
1550        ErrorCode::QUERY_PROJECTION_TEXT_INPUT_REQUIRED,
1551        ErrorCode::QUERY_PROJECTION_TEXT_OR_NULL_ARGUMENT_REQUIRED,
1552        ErrorCode::QUERY_PROJECTION_INTEGER_OR_NULL_ARGUMENT_REQUIRED,
1553        ErrorCode::QUERY_PROJECTION_UNARY_OPERAND_INCOMPATIBLE,
1554        ErrorCode::QUERY_PROJECTION_BINARY_OPERANDS_INCOMPATIBLE,
1555        ErrorCode::QUERY_RESULT_SHAPE_MISMATCH,
1556        ErrorCode::QUERY_RESULT_EXPECTED_ROWS,
1557        ErrorCode::QUERY_RESULT_EXPECTED_GROUPED,
1558        ErrorCode::SQL_LOWERING_ENTITY_MISMATCH,
1559        ErrorCode::SQL_LOWERING_SELECT_PROJECTION_SHAPE,
1560        ErrorCode::SQL_LOWERING_SELECT_DISTINCT,
1561        ErrorCode::SQL_LOWERING_DISTINCT_ORDER_BY_PROJECTION,
1562        ErrorCode::SQL_LOWERING_GLOBAL_AGGREGATE_PROJECTION,
1563        ErrorCode::SQL_LOWERING_GLOBAL_AGGREGATE_GROUP_BY,
1564        ErrorCode::SQL_LOWERING_SELECT_GROUP_BY_SHAPE,
1565        ErrorCode::SQL_LOWERING_GROUPED_PROJECTION_EXPLICIT_LIST_REQUIRED,
1566        ErrorCode::SQL_LOWERING_GROUPED_PROJECTION_AGGREGATE_REQUIRED,
1567        ErrorCode::SQL_LOWERING_GROUPED_PROJECTION_NON_GROUP_FIELD,
1568        ErrorCode::SQL_LOWERING_GROUPED_PROJECTION_SCALAR_AFTER_AGGREGATE,
1569        ErrorCode::SQL_LOWERING_HAVING_REQUIRES_GROUP_BY,
1570        ErrorCode::SQL_LOWERING_SELECT_HAVING_SHAPE,
1571        ErrorCode::SQL_LOWERING_AGGREGATE_INPUT_EXPRESSIONS,
1572        ErrorCode::SQL_LOWERING_WHERE_EXPRESSION_SHAPE,
1573        ErrorCode::SQL_LOWERING_PARAMETER_PLACEMENT,
1574        ErrorCode::SQL_LOWERING_SQL_DDL_EXECUTION_UNSUPPORTED,
1575    ];
1576
1577    #[test]
1578    fn diagnostic_from_code_uses_default_origin() {
1579        let diagnostic = Diagnostic::from_code(DiagnosticCode::QueryPlan);
1580
1581        assert_eq!(diagnostic.code(), DiagnosticCode::QueryPlan);
1582        assert_eq!(diagnostic.origin(), ErrorOrigin::Query);
1583    }
1584
1585    #[test]
1586    fn diagnostic_code_reports_broad_class() {
1587        assert_eq!(
1588            DiagnosticCode::QueryUnsupportedSqlFeature.class(),
1589            ErrorClass::Unsupported
1590        );
1591        assert_eq!(
1592            DiagnosticCode::QuerySqlSurfaceMismatch.class(),
1593            ErrorClass::Unsupported
1594        );
1595        assert_eq!(DiagnosticCode::QueryPlan.class(), ErrorClass::Query);
1596        assert_eq!(
1597            DiagnosticCode::StoreCorruption.class(),
1598            ErrorClass::Corruption
1599        );
1600    }
1601
1602    #[test]
1603    fn public_error_codes_are_sequential() {
1604        for (index, code) in ORDERED_ERROR_CODES.iter().enumerate() {
1605            let expected = u16::try_from(index + 1).expect("test error-code index fits u16");
1606            assert_eq!(code.raw(), expected);
1607        }
1608    }
1609
1610    #[test]
1611    fn public_error_codes_reconstruct_shifted_details() {
1612        assert_eq!(
1613            ErrorCode::QUERY_UNKNOWN_AGGREGATE_TARGET_FIELD.diagnostic_code(),
1614            DiagnosticCode::QueryUnknownAggregateTargetField
1615        );
1616        assert_eq!(
1617            ErrorCode::SQL_FEATURE_JOIN.diagnostic_detail(),
1618            Some(DiagnosticDetail::UnsupportedSqlFeature {
1619                feature: SqlFeatureCode::Join,
1620            })
1621        );
1622        assert_eq!(
1623            ErrorCode::QUERY_PROJECTION_NUMERIC_LITERAL_REQUIRED.diagnostic_detail(),
1624            Some(DiagnosticDetail::QueryProjection {
1625                reason: QueryProjectionCode::NumericLiteralRequired,
1626            })
1627        );
1628        assert_eq!(
1629            ErrorCode::SQL_LOWERING_DISTINCT_ORDER_BY_PROJECTION.diagnostic_detail(),
1630            Some(DiagnosticDetail::SqlLowering {
1631                reason: SqlLoweringCode::DistinctOrderByProjection,
1632            })
1633        );
1634    }
1635}