use std::fmt;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct FeatureId(&'static str);
impl FeatureId {
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl fmt::Display for FeatureId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
macro_rules! feature_ids {
($($name:ident = $id:literal => $display:literal;)*) => {
impl FeatureId {
$(
#[doc = concat!("`", $display, "`")]
pub const $name: FeatureId = FeatureId($id);
)*
}
pub const REFERENCED_FEATURES: &[(FeatureId, &str)] = &[
$((FeatureId::$name, $display),)*
];
};
}
feature_ids! {
G002 = "G002" => "Different-edges match mode";
G003 = "G003" => "Explicit REPEATABLE ELEMENTS keyword";
G010 = "G010" => "Explicit WALK keyword";
G011 = "G011" => "Advanced path modes: TRAIL";
G012 = "G012" => "Advanced path modes: SIMPLE";
G013 = "G013" => "Advanced path modes: ACYCLIC";
G014 = "G014" => "Explicit PATH/PATHS keywords";
G015 = "G015" => "All path search: explicit ALL keyword";
G016 = "G016" => "Any path search";
G017 = "G017" => "All shortest path search";
G018 = "G018" => "Any shortest path search";
G019 = "G019" => "Counted shortest path search";
G020 = "G020" => "Counted shortest group search";
G036 = "G036" => "Quantified edges";
G037 = "G037" => "Questioned paths";
G060 = "G060" => "Bounded graph pattern quantifiers";
G061 = "G061" => "Unbounded graph pattern quantifiers";
G100 = "G100" => "ELEMENT_ID function";
G110 = "G110" => "IS DIRECTED predicate";
G111 = "G111" => "IS LABELED predicate";
G112 = "G112" => "IS SOURCE and IS DESTINATION predicate";
G113 = "G113" => "ALL_DIFFERENT predicate";
G114 = "G114" => "SAME predicate";
G115 = "G115" => "PROPERTY_EXISTS predicate";
GA01 = "GA01" => "IEEE 754 floating point operations";
GA07 = "GA07" => "Ordering by discarded binding variables";
GC02 = "GC02" => "Graph schema management: IF [ NOT ] EXISTS";
GC03 = "GC03" => "Graph type: IF [ NOT ] EXISTS";
GC04 = "GC04" => "Graph management";
GC05 = "GC05" => "Graph management: IF [ NOT ] EXISTS";
GD01 = "GD01" => "Updatable graphs";
GE04 = "GE04" => "Graph parameters";
GE05 = "GE05" => "Binding table parameters";
GE06 = "GE06" => "Path value construction";
GE07 = "GE07" => "Boolean XOR";
GE08 = "GE08" => "Reference parameters";
GA05 = "GA05" => "Cast specification";
GA06 = "GA06" => "Value type predicate";
GF01 = "GF01" => "Enhanced numeric functions";
GF02 = "GF02" => "Trigonometric functions";
GF03 = "GF03" => "Logarithmic functions";
GF04 = "GF04" => "Enhanced path functions";
GF05 = "GF05" => "Multi-character TRIM function";
GF06 = "GF06" => "Explicit TRIM function";
GF07 = "GF07" => "Byte string TRIM function";
GF10 = "GF10" => "Advanced aggregate functions: general set functions";
GF11 = "GF11" => "Advanced aggregate functions: binary set functions";
GF12 = "GF12" => "CARDINALITY function";
GF13 = "GF13" => "SIZE function";
GF20 = "GF20" => "Aggregate functions in sort keys";
GL01 = "GL01" => "Hexadecimal literals";
GL02 = "GL02" => "Octal literals";
GL03 = "GL03" => "Binary literals";
GL04 = "GL04" => "Exact number in common notation without suffix";
GL05 = "GL05" => "Exact number in common notation or as decimal integer with suffix";
GL06 = "GL06" => "Exact number in scientific notation with suffix";
GL07 = "GL07" => "Approximate number in common notation or as decimal integer with suffix";
GL08 = "GL08" => "Approximate number in scientific notation with suffix";
GL09 = "GL09" => "Optional float number suffix";
GL10 = "GL10" => "Optional double number suffix";
GL11 = "GL11" => "Opt-out character escaping";
IM_UUID = "IM_UUID" => "selene-db UUID extension";
IM_JSON = "IM_JSON" => "selene-db JSON extension";
IM_VECTOR = "IM_VECTOR" => "selene-db VECTOR extension";
IM_EXTENDS = "IM_EXTENDS" => "selene-db EXTENDS type composition extension";
IM_INDEX_DDL = "IM_INDEX_DDL" => "selene-db named index DDL extension";
IM_TYPED_PARAMS = "IM_TYPED_PARAMS" => "selene-db inline typed parameter declaration extension";
IM_TRUNCATE = "IM_TRUNCATE" => "selene-db bulk truncate extension";
IM_DROP_CASCADE = "IM_DROP_CASCADE" => "selene-db cascading DROP TYPE extension";
IM_DROP_GRAPH = "IM_DROP_GRAPH" => "selene-db DROP GRAPH factory-reset extension";
GH02 = "GH02" => "Undirected edge patterns";
GG01 = "GG01" => "Graph with an open graph type";
GG02 = "GG02" => "Graph with a closed graph type";
GG20 = "GG20" => "Explicit element type names";
GG21 = "GG21" => "Explicit element type key label sets";
GP01 = "GP01" => "Inline procedure";
GP02 = "GP02" => "Inline procedure with implicit nested variable scope";
GP03 = "GP03" => "Inline procedure with explicit nested variable scope";
GP04 = "GP04" => "Named procedure calls";
GP05 = "GP05" => "Procedure-local value variable definitions";
GP06 = "GP06" => "Procedure-local value variable definitions: value variables based on simple expressions";
GP07 = "GP07" => "Procedure-local value variable definitions: value variable based on subqueries";
GP08 = "GP08" => "Procedure-local binding table variable definitions";
GP09 = "GP09" => "Procedure-local binding table variable definitions: binding table variables based on simple expressions or references";
GP10 = "GP10" => "Procedure-local binding table variable definitions: binding table variables based on subqueries";
GP11 = "GP11" => "Procedure-local graph variable definitions";
GP12 = "GP12" => "Procedure-local graph variable definitions: graph variables based on simple expressions or references";
GP13 = "GP13" => "Procedure-local graph variable definitions: graph variables based on subqueries";
GP14 = "GP14" => "Binding tables as procedure arguments";
GP15 = "GP15" => "Graphs as procedure arguments";
GP18 = "GP18" => "Catalog and data statement mixing";
GQ02 = "GQ02" => "Composite query: OTHERWISE";
GQ03 = "GQ03" => "Composite query: UNION";
GQ04 = "GQ04" => "Composite query: EXCEPT DISTINCT";
GQ05 = "GQ05" => "Composite query: EXCEPT ALL";
GQ06 = "GQ06" => "Composite query: INTERSECT DISTINCT";
GQ07 = "GQ07" => "Composite query: INTERSECT ALL";
GQ08 = "GQ08" => "FILTER statement";
GQ09 = "GQ09" => "LET statement";
GQ10 = "GQ10" => "FOR statement: list value support";
GQ11 = "GQ11" => "FOR statement: WITH ORDINALITY";
GQ12 = "GQ12" => "ORDER BY and page statement: OFFSET clause";
GQ13 = "GQ13" => "ORDER BY and page statement: LIMIT clause";
GQ14 = "GQ14" => "Complex expressions in sort keys";
GQ15 = "GQ15" => "GROUP BY clause";
GQ16 = "GQ16" => "Pre-projection aliases in sort keys";
GQ18 = "GQ18" => "Scalar subqueries";
GQ20 = "GQ20" => "Advanced linear composition with NEXT";
GQ24 = "GQ24" => "FOR statement: WITH OFFSET";
GS01 = "GS01" => "SESSION SET command: session-local graph parameters";
GS02 = "GS02" => "SESSION SET command: session-local binding table parameters";
GS03 = "GS03" => "SESSION SET command: session-local value parameters";
GS04 = "GS04" => "SESSION RESET command: reset all characteristics";
GS05 = "GS05" => "SESSION RESET command: reset session schema";
GS06 = "GS06" => "SESSION RESET command: reset session graph";
GS07 = "GS07" => "SESSION RESET command: reset time zone displacement";
GS08 = "GS08" => "SESSION RESET command: reset all session parameters";
GS10 = "GS10" => "SESSION SET command: session-local binding table parameters based on subqueries";
GS11 = "GS11" => "SESSION SET command: session-local value parameters based on subqueries";
GS12 = "GS12" => "SESSION SET command: session-local graph parameters based on simple expressions or references";
GS13 = "GS13" => "SESSION SET command: session-local binding table parameters based on simple expressions or references";
GS14 = "GS14" => "SESSION SET command: session-local value parameters based on simple expressions";
GS15 = "GS15" => "SESSION SET command: set time zone displacement";
GS16 = "GS16" => "SESSION RESET command: reset individual session parameters";
GT01 = "GT01" => "Explicit transaction commands";
GT03 = "GT03" => "Use of multiple graphs in a transaction";
GV01 = "GV01" => "8 bit unsigned integer numbers";
GV02 = "GV02" => "8 bit signed integer numbers";
GV03 = "GV03" => "16 bit unsigned integer numbers";
GV04 = "GV04" => "16 bit signed integer numbers";
GV05 = "GV05" => "Small unsigned integer numbers";
GV06 = "GV06" => "32 bit unsigned integer numbers";
GV07 = "GV07" => "32 bit signed integer numbers";
GV08 = "GV08" => "Regular unsigned integer numbers";
GV09 = "GV09" => "Specified integer number precision";
GV10 = "GV10" => "Big unsigned integer numbers";
GV11 = "GV11" => "64 bit unsigned integer numbers";
GV12 = "GV12" => "64 bit signed integer numbers";
GV13 = "GV13" => "128 bit unsigned integer numbers";
GV14 = "GV14" => "128 bit signed integer numbers";
GV15 = "GV15" => "256 bit unsigned integer numbers";
GV16 = "GV16" => "256 bit signed integer numbers";
GV17 = "GV17" => "Decimal numbers";
GV18 = "GV18" => "Small signed integer numbers";
GV19 = "GV19" => "Big signed integer numbers";
GV20 = "GV20" => "16 bit floating point numbers";
GV21 = "GV21" => "32 bit floating point numbers";
GV22 = "GV22" => "Specified floating point number precision";
GV23 = "GV23" => "Floating point type name synonyms";
GV24 = "GV24" => "64 bit floating point numbers";
GV25 = "GV25" => "128 bit floating point numbers";
GV26 = "GV26" => "256 bit floating point numbers";
GV30 = "GV30" => "Specified character string minimum length";
GV31 = "GV31" => "Specified character string maximum length";
GV32 = "GV32" => "Specified character string fixed length";
GV35 = "GV35" => "Byte string types";
GV36 = "GV36" => "Specified byte string minimum length";
GV37 = "GV37" => "Specified byte string maximum length";
GV38 = "GV38" => "Specified byte string fixed length";
GV39 = "GV39" => "Temporal types: date, local datetime and local time support";
GV40 = "GV40" => "Temporal types: zoned datetime and zoned time support";
GV41 = "GV41" => "Temporal types: duration support";
GV45 = "GV45" => "Record types";
GV46 = "GV46" => "Closed record types";
GV47 = "GV47" => "Open record types";
GV48 = "GV48" => "Nested record types";
GV50 = "GV50" => "List value types";
GV55 = "GV55" => "Path value types";
GV60 = "GV60" => "Graph reference value types";
GV61 = "GV61" => "Binding table reference value types";
GV66 = "GV66" => "Open dynamic union types";
GV67 = "GV67" => "Closed dynamic union types";
GV68 = "GV68" => "Dynamic property value types";
GV90 = "GV90" => "Explicit value type nullability";
}
pub const SUPPORTED_FEATURES: &[FeatureId] = &[
FeatureId::G002,
FeatureId::G003,
FeatureId::G010,
FeatureId::G011,
FeatureId::G012,
FeatureId::G013,
FeatureId::G014,
FeatureId::G015,
FeatureId::G016,
FeatureId::G017,
FeatureId::G018,
FeatureId::G019,
FeatureId::G020,
FeatureId::G036,
FeatureId::G037,
FeatureId::G060,
FeatureId::G061,
FeatureId::G100,
FeatureId::G110,
FeatureId::G111,
FeatureId::G112,
FeatureId::G113,
FeatureId::G114,
FeatureId::G115,
FeatureId::GA01,
FeatureId::GA05,
FeatureId::GA06,
FeatureId::GA07,
FeatureId::GC03,
FeatureId::GD01,
FeatureId::GE04,
FeatureId::GE05,
FeatureId::GE06,
FeatureId::GE07,
FeatureId::GF01,
FeatureId::GF02,
FeatureId::GF03,
FeatureId::GF04,
FeatureId::GF05,
FeatureId::GF06,
FeatureId::GF07,
FeatureId::GF10,
FeatureId::GF11,
FeatureId::GF12,
FeatureId::GF13,
FeatureId::GF20,
FeatureId::GL01,
FeatureId::GL02,
FeatureId::GL03,
FeatureId::GL04,
FeatureId::GL05,
FeatureId::GL06,
FeatureId::GL07,
FeatureId::GL08,
FeatureId::GL09,
FeatureId::GL10,
FeatureId::GL11,
FeatureId::IM_UUID,
FeatureId::IM_JSON,
FeatureId::IM_VECTOR,
FeatureId::IM_EXTENDS,
FeatureId::IM_INDEX_DDL,
FeatureId::IM_TYPED_PARAMS,
FeatureId::IM_TRUNCATE,
FeatureId::IM_DROP_CASCADE,
FeatureId::IM_DROP_GRAPH,
FeatureId::GH02,
FeatureId::GG01,
FeatureId::GG02,
FeatureId::GG20,
FeatureId::GG21,
FeatureId::GP01,
FeatureId::GP02,
FeatureId::GP03,
FeatureId::GP04,
FeatureId::GQ02,
FeatureId::GQ03,
FeatureId::GQ04,
FeatureId::GQ05,
FeatureId::GQ06,
FeatureId::GQ07,
FeatureId::GQ08,
FeatureId::GQ09,
FeatureId::GQ10,
FeatureId::GQ11,
FeatureId::GQ12,
FeatureId::GQ13,
FeatureId::GQ14,
FeatureId::GQ15,
FeatureId::GQ16,
FeatureId::GQ18,
FeatureId::GQ20,
FeatureId::GQ24,
FeatureId::GS03,
FeatureId::GS04,
FeatureId::GS07,
FeatureId::GS08,
FeatureId::GS15,
FeatureId::GS16,
FeatureId::GT01,
FeatureId::GV01,
FeatureId::GV02,
FeatureId::GV03,
FeatureId::GV04,
FeatureId::GV05,
FeatureId::GV06,
FeatureId::GV07,
FeatureId::GV08,
FeatureId::GV09,
FeatureId::GV10,
FeatureId::GV11,
FeatureId::GV12,
FeatureId::GV13,
FeatureId::GV14,
FeatureId::GV17,
FeatureId::GV18,
FeatureId::GV19,
FeatureId::GV21,
FeatureId::GV22,
FeatureId::GV23,
FeatureId::GV24,
FeatureId::GV30,
FeatureId::GV31,
FeatureId::GV32,
FeatureId::GV35,
FeatureId::GV36,
FeatureId::GV37,
FeatureId::GV38,
FeatureId::GV39,
FeatureId::GV40,
FeatureId::GV41,
FeatureId::GV45,
FeatureId::GV46,
FeatureId::GV47,
FeatureId::GV48,
FeatureId::GV50,
FeatureId::GV55,
FeatureId::GV66,
FeatureId::GV67,
FeatureId::GV68,
FeatureId::GV90,
];
pub const NOT_SUPPORTED_RATIONALE: &[(FeatureId, &str)] = &[
(
FeatureId::GP05,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP06,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP07,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP08,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP09,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP10,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP11,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP12,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP13,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP14,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP15,
"procedure-local definitions require the procedure body parser; not yet supported",
),
(
FeatureId::GP18,
"mixed catalog/data transaction behavior remains forbidden",
),
(
FeatureId::GC02,
"CREATE/DROP SCHEMA is outside the current catalog claim (graph-schema vs graph-type vs graph)",
),
(
FeatureId::GC04,
"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",
),
(
FeatureId::GC05,
"CREATE GRAPH IF NOT EXISTS modifier remains outside the current catalog claim",
),
(
FeatureId::GS01,
"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",
),
(
FeatureId::GS02,
"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",
),
(
FeatureId::GS05,
"SESSION RESET SCHEMA resets the session schema; D1 single-graph embeddable has no schema layer (section 4.2.5.1) to reset",
),
(
FeatureId::GS06,
"SESSION RESET GRAPH resets the session graph; D1 single-graph embeddable has exactly one graph and no working-graph switch to reset",
),
(
FeatureId::GS10,
"session-local binding table parameters from subqueries depend on GS02 (binding-table parameters) and a procedure body; both deferred under D1",
),
(
FeatureId::GS11,
"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",
),
(
FeatureId::GS12,
"session-local graph parameters from simple graph expressions/references depend on GS01 (graph parameters); D1-blocked",
),
(
FeatureId::GS13,
"session-local binding table parameters from simple expressions/references depend on GS02 (binding-table parameters); deferred",
),
(
FeatureId::GS14,
"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",
),
(
FeatureId::GT03,
"multi-graph transactions are out of scope under the D1 single-graph embeddable model",
),
(
FeatureId::GV15,
"256-bit unsigned integers are not represented in Value v1",
),
(
FeatureId::GV16,
"256-bit signed integers are not represented in Value v1",
),
(FeatureId::GV20, "FLOAT16 remains deferred"),
(FeatureId::GV25, "FLOAT128 is deferred"),
(FeatureId::GV26, "FLOAT256 is deferred"),
(
FeatureId::GV60,
"GRAPH reference type spellings parse to the Flagger, but graph reference value semantics and closed graph constraints remain deferred",
),
(
FeatureId::GV61,
"binding table reference types require TABLE field-type descriptors and binding-table value semantics before claiming",
),
];
mod annex_b;
pub use annex_b::{ANNEX_B_REGISTER, AnnexBId, ImplDefinedChoice};
pub fn is_supported(id: FeatureId) -> bool {
SUPPORTED_FEATURES.contains(&id)
}
pub fn name_of(id: FeatureId) -> Option<&'static str> {
REFERENCED_FEATURES
.iter()
.find_map(|(feature, name)| (*feature == id).then_some(*name))
}
pub fn feature_id_from_str(id: &str) -> Option<FeatureId> {
REFERENCED_FEATURES
.iter()
.find_map(|(feature, _)| (feature.as_str() == id).then_some(*feature))
}
pub fn non_supported_rationale(id: FeatureId) -> Option<&'static str> {
NOT_SUPPORTED_RATIONALE
.iter()
.find_map(|(feature, rationale)| (*feature == id).then_some(*rationale))
}
#[cfg(test)]
mod tests;