1use std::fmt;
8
9#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
14#[repr(transparent)]
15pub struct FeatureId(&'static str);
16
17impl FeatureId {
18 pub const fn as_str(self) -> &'static str {
20 self.0
21 }
22}
23
24impl fmt::Display for FeatureId {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.write_str(self.as_str())
27 }
28}
29
30macro_rules! feature_ids {
31 ($($name:ident = $id:literal => $display:literal;)*) => {
32 impl FeatureId {
33 $(
34 #[doc = concat!("`", $display, "`")]
35 pub const $name: FeatureId = FeatureId($id);
36 )*
37 }
38
39 pub const REFERENCED_FEATURES: &[(FeatureId, &str)] = &[
41 $((FeatureId::$name, $display),)*
42 ];
43 };
44}
45
46feature_ids! {
47 G002 = "G002" => "Different-edges match mode";
48 G003 = "G003" => "Explicit REPEATABLE ELEMENTS keyword";
49 G010 = "G010" => "Explicit WALK keyword";
50 G011 = "G011" => "Advanced path modes: TRAIL";
51 G012 = "G012" => "Advanced path modes: SIMPLE";
52 G013 = "G013" => "Advanced path modes: ACYCLIC";
53 G014 = "G014" => "Explicit PATH/PATHS keywords";
54 G015 = "G015" => "All path search: explicit ALL keyword";
55 G016 = "G016" => "Any path search";
56 G017 = "G017" => "All shortest path search";
57 G018 = "G018" => "Any shortest path search";
58 G019 = "G019" => "Counted shortest path search";
59 G020 = "G020" => "Counted shortest group search";
60 G036 = "G036" => "Quantified edges";
61 G037 = "G037" => "Questioned paths";
62 G060 = "G060" => "Bounded graph pattern quantifiers";
63 G061 = "G061" => "Unbounded graph pattern quantifiers";
64 G100 = "G100" => "ELEMENT_ID function";
65 G110 = "G110" => "IS DIRECTED predicate";
66 G111 = "G111" => "IS LABELED predicate";
67 G112 = "G112" => "IS SOURCE and IS DESTINATION predicate";
68 G113 = "G113" => "ALL_DIFFERENT predicate";
69 G114 = "G114" => "SAME predicate";
70 G115 = "G115" => "PROPERTY_EXISTS predicate";
71 GA01 = "GA01" => "IEEE 754 floating point operations";
72 GA07 = "GA07" => "Ordering by discarded binding variables";
73 GC02 = "GC02" => "Graph schema management: IF [ NOT ] EXISTS";
74 GC03 = "GC03" => "Graph type: IF [ NOT ] EXISTS";
75 GC04 = "GC04" => "Graph management";
76 GC05 = "GC05" => "Graph management: IF [ NOT ] EXISTS";
77 GD01 = "GD01" => "Updatable graphs";
78 GE04 = "GE04" => "Graph parameters";
79 GE05 = "GE05" => "Binding table parameters";
80 GE06 = "GE06" => "Path value construction";
81 GE07 = "GE07" => "Boolean XOR";
82 GE08 = "GE08" => "Reference parameters";
94 GA05 = "GA05" => "Cast specification";
95 GA06 = "GA06" => "Value type predicate";
96 GF01 = "GF01" => "Enhanced numeric functions";
97 GF02 = "GF02" => "Trigonometric functions";
98 GF03 = "GF03" => "Logarithmic functions";
99 GF04 = "GF04" => "Enhanced path functions";
100 GF05 = "GF05" => "Multi-character TRIM function";
101 GF06 = "GF06" => "Explicit TRIM function";
102 GF07 = "GF07" => "Byte string TRIM function";
103 GF10 = "GF10" => "Advanced aggregate functions: general set functions";
104 GF11 = "GF11" => "Advanced aggregate functions: binary set functions";
105 GF12 = "GF12" => "CARDINALITY function";
106 GF13 = "GF13" => "SIZE function";
107 GF20 = "GF20" => "Aggregate functions in sort keys";
108 GL01 = "GL01" => "Hexadecimal literals";
109 GL02 = "GL02" => "Octal literals";
110 GL03 = "GL03" => "Binary literals";
111 GL04 = "GL04" => "Exact number in common notation without suffix";
112 GL05 = "GL05" => "Exact number in common notation or as decimal integer with suffix";
113 GL06 = "GL06" => "Exact number in scientific notation with suffix";
114 GL07 = "GL07" => "Approximate number in common notation or as decimal integer with suffix";
115 GL08 = "GL08" => "Approximate number in scientific notation with suffix";
116 GL09 = "GL09" => "Optional float number suffix";
117 GL10 = "GL10" => "Optional double number suffix";
118 GL11 = "GL11" => "Opt-out character escaping";
119 IM_UUID = "IM_UUID" => "selene-db UUID extension";
120 IM_JSON = "IM_JSON" => "selene-db JSON extension";
121 IM_VECTOR = "IM_VECTOR" => "selene-db VECTOR extension";
122 IM_EXTENDS = "IM_EXTENDS" => "selene-db EXTENDS type composition extension";
123 IM_INDEX_DDL = "IM_INDEX_DDL" => "selene-db named index DDL extension";
124 IM_TYPED_PARAMS = "IM_TYPED_PARAMS" => "selene-db inline typed parameter declaration extension";
125 IM_TRUNCATE = "IM_TRUNCATE" => "selene-db bulk truncate extension";
126 IM_DROP_CASCADE = "IM_DROP_CASCADE" => "selene-db cascading DROP TYPE extension";
127 IM_DROP_GRAPH = "IM_DROP_GRAPH" => "selene-db DROP GRAPH factory-reset extension";
128 GH02 = "GH02" => "Undirected edge patterns";
129 GG01 = "GG01" => "Graph with an open graph type";
130 GG02 = "GG02" => "Graph with a closed graph type";
131 GG20 = "GG20" => "Explicit element type names";
132 GG21 = "GG21" => "Explicit element type key label sets";
133 GP01 = "GP01" => "Inline procedure";
134 GP02 = "GP02" => "Inline procedure with implicit nested variable scope";
135 GP03 = "GP03" => "Inline procedure with explicit nested variable scope";
136 GP04 = "GP04" => "Named procedure calls";
137 GP05 = "GP05" => "Procedure-local value variable definitions";
138 GP06 = "GP06" => "Procedure-local value variable definitions: value variables based on simple expressions";
139 GP07 = "GP07" => "Procedure-local value variable definitions: value variable based on subqueries";
140 GP08 = "GP08" => "Procedure-local binding table variable definitions";
141 GP09 = "GP09" => "Procedure-local binding table variable definitions: binding table variables based on simple expressions or references";
142 GP10 = "GP10" => "Procedure-local binding table variable definitions: binding table variables based on subqueries";
143 GP11 = "GP11" => "Procedure-local graph variable definitions";
144 GP12 = "GP12" => "Procedure-local graph variable definitions: graph variables based on simple expressions or references";
145 GP13 = "GP13" => "Procedure-local graph variable definitions: graph variables based on subqueries";
146 GP14 = "GP14" => "Binding tables as procedure arguments";
147 GP15 = "GP15" => "Graphs as procedure arguments";
148 GP18 = "GP18" => "Catalog and data statement mixing";
149 GQ02 = "GQ02" => "Composite query: OTHERWISE";
150 GQ03 = "GQ03" => "Composite query: UNION";
151 GQ04 = "GQ04" => "Composite query: EXCEPT DISTINCT";
152 GQ05 = "GQ05" => "Composite query: EXCEPT ALL";
153 GQ06 = "GQ06" => "Composite query: INTERSECT DISTINCT";
154 GQ07 = "GQ07" => "Composite query: INTERSECT ALL";
155 GQ08 = "GQ08" => "FILTER statement";
156 GQ09 = "GQ09" => "LET statement";
157 GQ10 = "GQ10" => "FOR statement: list value support";
158 GQ11 = "GQ11" => "FOR statement: WITH ORDINALITY";
159 GQ12 = "GQ12" => "ORDER BY and page statement: OFFSET clause";
160 GQ13 = "GQ13" => "ORDER BY and page statement: LIMIT clause";
161 GQ14 = "GQ14" => "Complex expressions in sort keys";
162 GQ15 = "GQ15" => "GROUP BY clause";
163 GQ16 = "GQ16" => "Pre-projection aliases in sort keys";
164 GQ18 = "GQ18" => "Scalar subqueries";
165 GQ20 = "GQ20" => "Advanced linear composition with NEXT";
166 GQ24 = "GQ24" => "FOR statement: WITH OFFSET";
167 GS01 = "GS01" => "SESSION SET command: session-local graph parameters";
168 GS02 = "GS02" => "SESSION SET command: session-local binding table parameters";
169 GS03 = "GS03" => "SESSION SET command: session-local value parameters";
170 GS04 = "GS04" => "SESSION RESET command: reset all characteristics";
171 GS05 = "GS05" => "SESSION RESET command: reset session schema";
172 GS06 = "GS06" => "SESSION RESET command: reset session graph";
173 GS07 = "GS07" => "SESSION RESET command: reset time zone displacement";
174 GS08 = "GS08" => "SESSION RESET command: reset all session parameters";
175 GS10 = "GS10" => "SESSION SET command: session-local binding table parameters based on subqueries";
176 GS11 = "GS11" => "SESSION SET command: session-local value parameters based on subqueries";
177 GS12 = "GS12" => "SESSION SET command: session-local graph parameters based on simple expressions or references";
178 GS13 = "GS13" => "SESSION SET command: session-local binding table parameters based on simple expressions or references";
179 GS14 = "GS14" => "SESSION SET command: session-local value parameters based on simple expressions";
180 GS15 = "GS15" => "SESSION SET command: set time zone displacement";
181 GS16 = "GS16" => "SESSION RESET command: reset individual session parameters";
182 GT01 = "GT01" => "Explicit transaction commands";
183 GT03 = "GT03" => "Use of multiple graphs in a transaction";
184 GV01 = "GV01" => "8 bit unsigned integer numbers";
185 GV02 = "GV02" => "8 bit signed integer numbers";
186 GV03 = "GV03" => "16 bit unsigned integer numbers";
187 GV04 = "GV04" => "16 bit signed integer numbers";
188 GV05 = "GV05" => "Small unsigned integer numbers";
189 GV06 = "GV06" => "32 bit unsigned integer numbers";
190 GV07 = "GV07" => "32 bit signed integer numbers";
191 GV08 = "GV08" => "Regular unsigned integer numbers";
192 GV09 = "GV09" => "Specified integer number precision";
193 GV10 = "GV10" => "Big unsigned integer numbers";
194 GV11 = "GV11" => "64 bit unsigned integer numbers";
195 GV12 = "GV12" => "64 bit signed integer numbers";
196 GV13 = "GV13" => "128 bit unsigned integer numbers";
197 GV14 = "GV14" => "128 bit signed integer numbers";
198 GV15 = "GV15" => "256 bit unsigned integer numbers";
199 GV16 = "GV16" => "256 bit signed integer numbers";
200 GV17 = "GV17" => "Decimal numbers";
201 GV18 = "GV18" => "Small signed integer numbers";
202 GV19 = "GV19" => "Big signed integer numbers";
203 GV20 = "GV20" => "16 bit floating point numbers";
204 GV21 = "GV21" => "32 bit floating point numbers";
205 GV22 = "GV22" => "Specified floating point number precision";
206 GV23 = "GV23" => "Floating point type name synonyms";
207 GV24 = "GV24" => "64 bit floating point numbers";
208 GV25 = "GV25" => "128 bit floating point numbers";
209 GV26 = "GV26" => "256 bit floating point numbers";
210 GV30 = "GV30" => "Specified character string minimum length";
211 GV31 = "GV31" => "Specified character string maximum length";
212 GV32 = "GV32" => "Specified character string fixed length";
213 GV35 = "GV35" => "Byte string types";
214 GV36 = "GV36" => "Specified byte string minimum length";
215 GV37 = "GV37" => "Specified byte string maximum length";
216 GV38 = "GV38" => "Specified byte string fixed length";
217 GV39 = "GV39" => "Temporal types: date, local datetime and local time support";
218 GV40 = "GV40" => "Temporal types: zoned datetime and zoned time support";
219 GV41 = "GV41" => "Temporal types: duration support";
220 GV45 = "GV45" => "Record types";
221 GV46 = "GV46" => "Closed record types";
222 GV47 = "GV47" => "Open record types";
223 GV48 = "GV48" => "Nested record types";
224 GV50 = "GV50" => "List value types";
225 GV55 = "GV55" => "Path value types";
226 GV60 = "GV60" => "Graph reference value types";
227 GV61 = "GV61" => "Binding table reference value types";
228 GV66 = "GV66" => "Open dynamic union types";
229 GV67 = "GV67" => "Closed dynamic union types";
230 GV68 = "GV68" => "Dynamic property value types";
231 GV90 = "GV90" => "Explicit value type nullability";
232}
233
234pub const SUPPORTED_FEATURES: &[FeatureId] = &[
239 FeatureId::G002,
240 FeatureId::G003,
241 FeatureId::G010,
242 FeatureId::G011,
243 FeatureId::G012,
244 FeatureId::G013,
245 FeatureId::G014,
251 FeatureId::G015,
252 FeatureId::G016,
253 FeatureId::G017,
254 FeatureId::G018,
255 FeatureId::G019,
256 FeatureId::G020,
257 FeatureId::G036,
258 FeatureId::G037,
259 FeatureId::G060,
260 FeatureId::G061,
261 FeatureId::G100,
262 FeatureId::G110,
263 FeatureId::G111,
264 FeatureId::G112,
265 FeatureId::G113,
266 FeatureId::G114,
267 FeatureId::G115,
268 FeatureId::GA01,
269 FeatureId::GA05,
270 FeatureId::GA06,
271 FeatureId::GA07,
272 FeatureId::GC03,
273 FeatureId::GD01,
274 FeatureId::GE04,
275 FeatureId::GE05,
276 FeatureId::GE06,
277 FeatureId::GE07,
278 FeatureId::GF01,
279 FeatureId::GF02,
280 FeatureId::GF03,
281 FeatureId::GF04,
282 FeatureId::GF05,
283 FeatureId::GF06,
284 FeatureId::GF07,
285 FeatureId::GF10,
286 FeatureId::GF11,
287 FeatureId::GF12,
288 FeatureId::GF13,
289 FeatureId::GF20,
290 FeatureId::GL01,
291 FeatureId::GL02,
292 FeatureId::GL03,
293 FeatureId::GL04,
294 FeatureId::GL05,
295 FeatureId::GL06,
296 FeatureId::GL07,
297 FeatureId::GL08,
298 FeatureId::GL09,
299 FeatureId::GL10,
300 FeatureId::GL11,
301 FeatureId::IM_UUID,
302 FeatureId::IM_JSON,
303 FeatureId::IM_VECTOR,
304 FeatureId::IM_EXTENDS,
305 FeatureId::IM_INDEX_DDL,
306 FeatureId::IM_TYPED_PARAMS,
307 FeatureId::IM_TRUNCATE,
308 FeatureId::IM_DROP_CASCADE,
309 FeatureId::IM_DROP_GRAPH,
310 FeatureId::GH02,
311 FeatureId::GG01,
312 FeatureId::GG02,
313 FeatureId::GG20,
314 FeatureId::GG21,
324 FeatureId::GP01,
325 FeatureId::GP02,
326 FeatureId::GP03,
327 FeatureId::GP04,
328 FeatureId::GQ02,
329 FeatureId::GQ03,
330 FeatureId::GQ04,
331 FeatureId::GQ05,
332 FeatureId::GQ06,
333 FeatureId::GQ07,
334 FeatureId::GQ08,
335 FeatureId::GQ09,
336 FeatureId::GQ10,
337 FeatureId::GQ11,
338 FeatureId::GQ12,
339 FeatureId::GQ13,
340 FeatureId::GQ14,
341 FeatureId::GQ15,
342 FeatureId::GQ16,
343 FeatureId::GQ18,
344 FeatureId::GQ20,
345 FeatureId::GQ24,
346 FeatureId::GS03,
347 FeatureId::GS04,
348 FeatureId::GS07,
349 FeatureId::GS08,
350 FeatureId::GS15,
351 FeatureId::GS16,
352 FeatureId::GT01,
353 FeatureId::GV01,
354 FeatureId::GV02,
355 FeatureId::GV03,
356 FeatureId::GV04,
357 FeatureId::GV05,
358 FeatureId::GV06,
359 FeatureId::GV07,
360 FeatureId::GV08,
361 FeatureId::GV09,
362 FeatureId::GV10,
363 FeatureId::GV11,
364 FeatureId::GV12,
365 FeatureId::GV13,
366 FeatureId::GV14,
367 FeatureId::GV17,
368 FeatureId::GV18,
369 FeatureId::GV19,
370 FeatureId::GV21,
371 FeatureId::GV22,
372 FeatureId::GV23,
373 FeatureId::GV24,
374 FeatureId::GV30,
375 FeatureId::GV31,
376 FeatureId::GV32,
377 FeatureId::GV35,
378 FeatureId::GV36,
379 FeatureId::GV37,
380 FeatureId::GV38,
381 FeatureId::GV39,
382 FeatureId::GV40,
383 FeatureId::GV41,
384 FeatureId::GV45,
385 FeatureId::GV46,
386 FeatureId::GV47,
387 FeatureId::GV48,
388 FeatureId::GV50,
389 FeatureId::GV55,
390 FeatureId::GV66,
391 FeatureId::GV67,
392 FeatureId::GV68,
393 FeatureId::GV90,
394];
395
396pub const NOT_SUPPORTED_RATIONALE: &[(FeatureId, &str)] = &[
413 (
414 FeatureId::GP05,
415 "procedure-local definitions require the procedure body parser; not yet supported",
416 ),
417 (
418 FeatureId::GP06,
419 "procedure-local definitions require the procedure body parser; not yet supported",
420 ),
421 (
422 FeatureId::GP07,
423 "procedure-local definitions require the procedure body parser; not yet supported",
424 ),
425 (
426 FeatureId::GP08,
427 "procedure-local definitions require the procedure body parser; not yet supported",
428 ),
429 (
430 FeatureId::GP09,
431 "procedure-local definitions require the procedure body parser; not yet supported",
432 ),
433 (
434 FeatureId::GP10,
435 "procedure-local definitions require the procedure body parser; not yet supported",
436 ),
437 (
438 FeatureId::GP11,
439 "procedure-local definitions require the procedure body parser; not yet supported",
440 ),
441 (
442 FeatureId::GP12,
443 "procedure-local definitions require the procedure body parser; not yet supported",
444 ),
445 (
446 FeatureId::GP13,
447 "procedure-local definitions require the procedure body parser; not yet supported",
448 ),
449 (
450 FeatureId::GP14,
451 "procedure-local definitions require the procedure body parser; not yet supported",
452 ),
453 (
454 FeatureId::GP15,
455 "procedure-local definitions require the procedure body parser; not yet supported",
456 ),
457 (
458 FeatureId::GP18,
459 "mixed catalog/data transaction behavior remains forbidden",
460 ),
461 (
462 FeatureId::GC02,
463 "CREATE/DROP SCHEMA is outside the current catalog claim (graph-schema vs graph-type vs graph)",
464 ),
465 (
466 FeatureId::GC04,
467 "CREATE GRAPH stays outside the current catalog claim (D1 single-graph embeddable cannot create a second graph); DROP GRAPH is the IM_DROP_GRAPH factory-reset extension, not GC04",
468 ),
469 (
470 FeatureId::GC05,
471 "CREATE GRAPH IF NOT EXISTS modifier remains outside the current catalog claim",
472 ),
473 (
474 FeatureId::GS01,
475 "SESSION SET <name> GRAPH binds a session-local graph parameter; D1 single-graph embeddable has one graph and no graph-parameter catalog/value slot to bind",
476 ),
477 (
478 FeatureId::GS02,
479 "SESSION SET <name> BINDING TABLE binds a typed binding-table reference value (GV61); the reference-type surface is deferred, so D1 has no spelling to bind",
480 ),
481 (
482 FeatureId::GS05,
483 "SESSION RESET SCHEMA resets the session schema; D1 single-graph embeddable has no schema layer (section 4.2.5.1) to reset",
484 ),
485 (
486 FeatureId::GS06,
487 "SESSION RESET GRAPH resets the session graph; D1 single-graph embeddable has exactly one graph and no working-graph switch to reset",
488 ),
489 (
490 FeatureId::GS10,
491 "session-local binding table parameters from subqueries depend on GS02 (binding-table parameters) and a procedure body; both deferred under D1",
492 ),
493 (
494 FeatureId::GS11,
495 "session-local value parameters from subqueries depend on procedure-body support; SESSION SET VALUE restricts the RHS to a value expression with no row context",
496 ),
497 (
498 FeatureId::GS12,
499 "session-local graph parameters from simple graph expressions/references depend on GS01 (graph parameters); D1-blocked",
500 ),
501 (
502 FeatureId::GS13,
503 "session-local binding table parameters from simple expressions/references depend on GS02 (binding-table parameters); deferred",
504 ),
505 (
506 FeatureId::GS14,
507 "selene-db evaluates SESSION SET VALUE against an empty binding so the RHS is restricted to a <value specification> (literal/parameter); the full <value expression> form (GS14) is not claimed",
508 ),
509 (
510 FeatureId::GT03,
511 "multi-graph transactions are out of scope under the D1 single-graph embeddable model",
512 ),
513 (
514 FeatureId::GV15,
515 "256-bit unsigned integers are not represented in Value v1",
516 ),
517 (
518 FeatureId::GV16,
519 "256-bit signed integers are not represented in Value v1",
520 ),
521 (FeatureId::GV20, "FLOAT16 remains deferred"),
522 (FeatureId::GV25, "FLOAT128 is deferred"),
523 (FeatureId::GV26, "FLOAT256 is deferred"),
524 (
525 FeatureId::GV60,
526 "GRAPH reference type spellings parse to the Flagger, but graph reference value semantics and closed graph constraints remain deferred",
527 ),
528 (
529 FeatureId::GV61,
530 "binding table reference types require TABLE field-type descriptors and binding-table value semantics before claiming",
531 ),
532];
533
534mod annex_b;
535
536pub use annex_b::{ANNEX_B_REGISTER, AnnexBId, ImplDefinedChoice};
537
538pub fn is_supported(id: FeatureId) -> bool {
540 SUPPORTED_FEATURES.contains(&id)
541}
542
543pub fn name_of(id: FeatureId) -> Option<&'static str> {
545 REFERENCED_FEATURES
546 .iter()
547 .find_map(|(feature, name)| (*feature == id).then_some(*name))
548}
549
550pub fn feature_id_from_str(id: &str) -> Option<FeatureId> {
552 REFERENCED_FEATURES
553 .iter()
554 .find_map(|(feature, _)| (feature.as_str() == id).then_some(*feature))
555}
556
557pub fn non_supported_rationale(id: FeatureId) -> Option<&'static str> {
559 NOT_SUPPORTED_RATIONALE
560 .iter()
561 .find_map(|(feature, rationale)| (*feature == id).then_some(*rationale))
562}
563
564#[cfg(test)]
565mod tests;