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