From 5152e27c84be176f3a62b102bb81248d2a89bd54 Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 20:06:29 +1000 Subject: [PATCH 1/6] feat(v3): add float4/float8 catalog rows + codegen reference SQL float4/float8 ScalarSpec rows (Float kind/fixture) in eql-scalars::CATALOG and the committed codegen reference baselines the generator parity gate checks against. --- crates/eql-scalars/src/fixture.rs | 1 + crates/eql-scalars/src/kind.rs | 12 + crates/eql-scalars/src/lib.rs | 73 +++- crates/eql-scalars/src/proptest_invariants.rs | 4 +- crates/eql-scalars/src/tests.rs | 116 ++++- .../reference/float4/float4_eq_functions.sql | 407 ++++++++++++++++++ .../reference/float4/float4_eq_operators.sql | 234 ++++++++++ .../reference/float4/float4_functions.sql | 404 +++++++++++++++++ .../reference/float4/float4_operators.sql | 228 ++++++++++ .../float4/float4_ord_aggregates.sql | 63 +++ .../reference/float4/float4_ord_functions.sql | 396 +++++++++++++++++ .../reference/float4/float4_ord_operators.sql | 246 +++++++++++ .../float4/float4_ord_ore_aggregates.sql | 63 +++ .../float4/float4_ord_ore_functions.sql | 396 +++++++++++++++++ .../float4/float4_ord_ore_operators.sql | 246 +++++++++++ .../codegen/reference/float4/float4_types.sql | 73 ++++ .../reference/float8/float8_eq_functions.sql | 407 ++++++++++++++++++ .../reference/float8/float8_eq_operators.sql | 234 ++++++++++ .../reference/float8/float8_functions.sql | 404 +++++++++++++++++ .../reference/float8/float8_operators.sql | 228 ++++++++++ .../float8/float8_ord_aggregates.sql | 63 +++ .../reference/float8/float8_ord_functions.sql | 396 +++++++++++++++++ .../reference/float8/float8_ord_operators.sql | 246 +++++++++++ .../float8/float8_ord_ore_aggregates.sql | 63 +++ .../float8/float8_ord_ore_functions.sql | 396 +++++++++++++++++ .../float8/float8_ord_ore_operators.sql | 246 +++++++++++ .../codegen/reference/float8/float8_types.sql | 73 ++++ 27 files changed, 5713 insertions(+), 5 deletions(-) create mode 100644 tests/codegen/reference/float4/float4_eq_functions.sql create mode 100644 tests/codegen/reference/float4/float4_eq_operators.sql create mode 100644 tests/codegen/reference/float4/float4_functions.sql create mode 100644 tests/codegen/reference/float4/float4_operators.sql create mode 100644 tests/codegen/reference/float4/float4_ord_aggregates.sql create mode 100644 tests/codegen/reference/float4/float4_ord_functions.sql create mode 100644 tests/codegen/reference/float4/float4_ord_operators.sql create mode 100644 tests/codegen/reference/float4/float4_ord_ore_aggregates.sql create mode 100644 tests/codegen/reference/float4/float4_ord_ore_functions.sql create mode 100644 tests/codegen/reference/float4/float4_ord_ore_operators.sql create mode 100644 tests/codegen/reference/float4/float4_types.sql create mode 100644 tests/codegen/reference/float8/float8_eq_functions.sql create mode 100644 tests/codegen/reference/float8/float8_eq_operators.sql create mode 100644 tests/codegen/reference/float8/float8_functions.sql create mode 100644 tests/codegen/reference/float8/float8_operators.sql create mode 100644 tests/codegen/reference/float8/float8_ord_aggregates.sql create mode 100644 tests/codegen/reference/float8/float8_ord_functions.sql create mode 100644 tests/codegen/reference/float8/float8_ord_operators.sql create mode 100644 tests/codegen/reference/float8/float8_ord_ore_aggregates.sql create mode 100644 tests/codegen/reference/float8/float8_ord_ore_functions.sql create mode 100644 tests/codegen/reference/float8/float8_ord_ore_operators.sql create mode 100644 tests/codegen/reference/float8/float8_types.sql diff --git a/crates/eql-scalars/src/fixture.rs b/crates/eql-scalars/src/fixture.rs index f1e3f9ac..431f4871 100644 --- a/crates/eql-scalars/src/fixture.rs +++ b/crates/eql-scalars/src/fixture.rs @@ -34,6 +34,7 @@ impl Fixture { | Fixture::Jsonb(_) | Fixture::Date(_) | Fixture::Timestamptz(_) + | Fixture::Float(_) | Fixture::Bool(_) => None, } } diff --git a/crates/eql-scalars/src/kind.rs b/crates/eql-scalars/src/kind.rs index 1219472c..4e83aed9 100644 --- a/crates/eql-scalars/src/kind.rs +++ b/crates/eql-scalars/src/kind.rs @@ -72,6 +72,8 @@ impl ScalarKind { | ScalarKind::Text | ScalarKind::Jsonb | ScalarKind::Bool + | ScalarKind::F32 + | ScalarKind::F64 | ScalarKind::Date | ScalarKind::Timestamptz => None, } @@ -97,6 +99,14 @@ impl ScalarKind { matches!(self, ScalarKind::Text) } + /// True for the IEEE-754 float kinds (`F32`, `F64`) — ordered, non-integer, + /// string-backed-fixture scalars whose `impl ScalarType` is hand-written in + /// `scalar_domains.rs` (like `text`/`numeric`). Keeps float classification in + /// the catalog crate alongside `is_int`/`is_temporal`/`is_text`. + pub const fn is_float(self) -> bool { + matches!(self, ScalarKind::F32 | ScalarKind::F64) + } + /// A debug/identifier string for the kind: the canonical Rust plaintext type /// name (`"i32"`, `"chrono::NaiveDate"`, `"rust_decimal::Decimal"`). `Jsonb` /// has **no generated SQL surface** and no catalog row, so calling this on it @@ -113,6 +123,8 @@ impl ScalarKind { ScalarKind::Timestamptz => "chrono::DateTime", ScalarKind::Numeric => "rust_decimal::Decimal", ScalarKind::Bool => "bool", + ScalarKind::F32 => "f32", + ScalarKind::F64 => "f64", ScalarKind::Jsonb => { panic!("ScalarKind::rust_type: jsonb has no generated surface yet") } diff --git a/crates/eql-scalars/src/lib.rs b/crates/eql-scalars/src/lib.rs index c48d77b1..3773ee46 100644 --- a/crates/eql-scalars/src/lib.rs +++ b/crates/eql-scalars/src/lib.rs @@ -80,6 +80,16 @@ pub enum ScalarKind { /// server-side. Like the other non-integer kinds, the bounded-numeric /// accessors are unreachable for it by construction. Bool, + /// 32-bit IEEE-754 binary float (`f32`, Postgres `real`/`float4`). + /// Ordered like the integer kinds via ORE, but with no i128 range + /// (`as_bounded_int()` returns `None`) and string-backed at the catalog + /// layer. Encrypts through the single f64 float crypto path + /// (`Plaintext::Float`) — the f32→f64 widening is exact and monotonic. + F32, + /// 64-bit IEEE-754 binary float (`f64`, Postgres `double precision`/ + /// `float8`). The native width of the float crypto path (`F32` widens into + /// it); otherwise classified exactly like [`ScalarKind::F32`]. + F64, } /// Always-present payload keys required by every generated domain CHECK, @@ -178,6 +188,12 @@ pub enum Fixture { /// storage-only, so this fixture is encrypted (ciphertext only, no index /// term) and never participates in a comparison pivot. Distinct by value. Bool(bool), + /// An IEEE-754 float plaintext rendered as a string (`"0.5"`, `"-inf"`). + /// The catalog stays zero-dep, so the string is parsed into `f32`/`f64` in + /// the SQLx harness, not here. Distinct by parsed value (the harness + /// `float_fixtures_are_distinct_by_value` guard enforces this). NaN and + /// `-0.0` are deliberately excluded; `±Inf` (`"inf"`/`"-inf"`) ARE fixtures. + Float(&'static str), } /// One generated public domain: a suffix appended to the type token and the @@ -221,6 +237,7 @@ macro_rules! fixtures { (date; $($s:literal),* $(,)?) => { &[$(Fixture::Date($s)),*] }; (timestamptz; $($s:literal),* $(,)?) => { &[$(Fixture::Timestamptz($s)),*] }; (bool; $($b:literal),* $(,)?) => { &[$(Fixture::Bool($b)),*] }; + (float; $($s:literal),* $(,)?) => { &[$(Fixture::Float($s)),*] }; } /// Domains shared by every ordered-integer scalar, in manifest file order: @@ -488,9 +505,63 @@ pub const TEXT: ScalarSpec = ScalarSpec { fixtures: TEXT_FIXTURES, }; +/// `float4` fixture plaintexts — IEEE-754 strings parsed into `f32` in the SQLx +/// harness (the catalog stays zero-dep). EVERY value is exactly representable in +/// f32 (powers of two and halves), so the `real` round-trip is lossless and the +/// f32→f64 widening before encryption is exact. The three pivots MUST be present +/// verbatim: `"-inf"` (min_pivot), `"0"` (origin/mid), `"inf"` (max_pivot). +/// NaN and `-0.0` are deliberately excluded (see the `float_special` suite). +/// Distinctness is enforced by `Fixture::Float` (above) and its guard test. +const FLOAT4_FIXTURES: &[Fixture] = fixtures!(float; + "-inf", "-1024", "-2.25", "-1", "-0.5", "-0.25", + "0", "0.25", "0.5", "1", "2.25", "1024", "inf"); + +/// `float8` fixture plaintexts — IEEE-754 strings parsed into `f64` in the SQLx +/// harness. The native width of the float crypto path; values span sign and +/// magnitude including subnormal-free interior points. The three pivots MUST be +/// present verbatim: `"-inf"` (min_pivot), `"0"` (origin/mid), `"inf"` +/// (max_pivot). NaN and `-0.0` are deliberately excluded. +const FLOAT8_FIXTURES: &[Fixture] = fixtures!(float; + "-inf", "-1e300", "-1000000", "-1.5", "-1", "-0.001", + "0", "0.001", "1", "1.5", "1000000", "1e300", "inf"); + +/// `float4` — an **ordered**, non-integer scalar (Postgres `real`). Reuses the +/// four-domain ordered shape (`ORDERED_INT_DOMAINS`); only kind and fixtures +/// differ. Both float widths encrypt through the SAME f64 crypto path +/// (`Plaintext::Float`), so `float4` vs `float8` is purely a Postgres-surface +/// distinction. Public (like `DATE`/`NUMERIC`) so the SQLx harness reads +/// `FLOAT4.fixtures` directly to parse the strings into `f32`. +pub const FLOAT4: ScalarSpec = ScalarSpec { + token: "float4", + kind: ScalarKind::F32, + domains: ORDERED_INT_DOMAINS, + fixtures: FLOAT4_FIXTURES, +}; + +/// `float8` — an **ordered**, non-integer scalar (Postgres `double precision`), +/// the native width of the float crypto path. Reuses the ordered shape. Public +/// so the SQLx harness reads `FLOAT8.fixtures` directly to parse into `f64`. +pub const FLOAT8: ScalarSpec = ScalarSpec { + token: "float8", + kind: ScalarKind::F64, + domains: ORDERED_INT_DOMAINS, + fixtures: FLOAT8_FIXTURES, +}; + /// The scalar catalog — the single source of truth. Order is significant (it /// drives generation order). New types are appended as their SQL surface lands. -pub const CATALOG: &[ScalarSpec] = &[INT4, INT2, INT8, DATE, TIMESTAMPTZ, NUMERIC, TEXT, BOOL]; +pub const CATALOG: &[ScalarSpec] = &[ + INT4, + INT2, + INT8, + DATE, + TIMESTAMPTZ, + NUMERIC, + TEXT, + BOOL, + FLOAT4, + FLOAT8, +]; /// Materialise an integer scalar's fixtures into a typed `&'static` slice at /// compile time. This is the **single-sourced** plaintext list the SQLx test diff --git a/crates/eql-scalars/src/proptest_invariants.rs b/crates/eql-scalars/src/proptest_invariants.rs index e5303a90..503e32c0 100644 --- a/crates/eql-scalars/src/proptest_invariants.rs +++ b/crates/eql-scalars/src/proptest_invariants.rs @@ -13,7 +13,7 @@ fn any_term() -> impl Strategy { prop_oneof![Just(Term::Hm), Just(Term::Ore), Just(Term::Bloom)] } -/// Strategy over the eight scalar kinds. +/// Strategy over the ten scalar kinds. fn any_kind() -> impl Strategy { prop_oneof![ Just(ScalarKind::I16), @@ -24,6 +24,8 @@ fn any_kind() -> impl Strategy { Just(ScalarKind::Jsonb), Just(ScalarKind::Date), Just(ScalarKind::Timestamptz), + Just(ScalarKind::F32), + Just(ScalarKind::F64), ] } diff --git a/crates/eql-scalars/src/tests.rs b/crates/eql-scalars/src/tests.rs index 80a2888f..b19d13d4 100644 --- a/crates/eql-scalars/src/tests.rs +++ b/crates/eql-scalars/src/tests.rs @@ -42,6 +42,8 @@ mod rust_tests { assert_eq!(ScalarKind::Jsonb.as_bounded_int(), None); assert_eq!(ScalarKind::Date.as_bounded_int(), None); assert_eq!(ScalarKind::Timestamptz.as_bounded_int(), None); + assert_eq!(ScalarKind::F32.as_bounded_int(), None); + assert_eq!(ScalarKind::F64.as_bounded_int(), None); } #[test] @@ -80,6 +82,8 @@ mod rust_tests { assert!(!ScalarKind::Jsonb.is_int()); assert!(!ScalarKind::Date.is_int()); assert!(!ScalarKind::Timestamptz.is_int()); + assert!(!ScalarKind::F32.is_int()); + assert!(!ScalarKind::F64.is_int()); } #[test] @@ -93,6 +97,8 @@ mod rust_tests { ScalarKind::Jsonb, ScalarKind::Date, ScalarKind::Timestamptz, + ScalarKind::F32, + ScalarKind::F64, ] { assert!(!k.is_text()); } @@ -171,6 +177,8 @@ mod rust_tests { assert!(!ScalarKind::I16.is_temporal()); assert!(!ScalarKind::I32.is_temporal()); assert!(!ScalarKind::I64.is_temporal()); + assert!(!ScalarKind::F32.is_temporal()); + assert!(!ScalarKind::F64.is_temporal()); } #[test] @@ -523,7 +531,7 @@ mod catalog_tests { } #[test] - fn catalog_has_int4_int2_int8_date_timestamptz_numeric_text_bool_in_order() { + fn catalog_has_all_tokens_in_order() { let tokens: Vec<&str> = CATALOG.iter().map(|s| s.token).collect(); assert_eq!( tokens, @@ -535,7 +543,9 @@ mod catalog_tests { "timestamptz", "numeric", "text", - "bool" + "bool", + "float4", + "float8" ] ); } @@ -896,6 +906,102 @@ mod values_tests { } } +mod float_tests { + use crate::*; + + fn scalar(token: &str) -> &'static ScalarSpec { + CATALOG + .iter() + .find(|s| s.token == token) + .unwrap_or_else(|| panic!("{token} missing from CATALOG")) + } + + #[test] + fn float_specs_are_in_catalog_with_ordered_shape() { + for token in ["float4", "float8"] { + let s = scalar(token); + let suffixes: Vec<_> = s.domains.iter().map(|d| d.suffix).collect(); + assert_eq!(suffixes, vec!["", "_eq", "_ord_ore", "_ord"]); + } + assert_eq!(scalar("float4").kind, ScalarKind::F32); + assert_eq!(scalar("float8").kind, ScalarKind::F64); + } + + #[test] + fn float_kinds_are_not_bounded_int_temporal_or_text() { + for k in [ScalarKind::F32, ScalarKind::F64] { + assert_eq!(k.as_bounded_int(), None); + assert!(!k.is_int()); + assert!(!k.is_temporal()); + assert!(!k.is_text()); + assert!(k.is_float()); + } + } + + #[test] + fn float_rust_types_are_f32_and_f64() { + assert_eq!(ScalarKind::F32.rust_type(), "f32"); + assert_eq!(ScalarKind::F64.rust_type(), "f64"); + } + + /// NaN and -0.0 must never be fixtures: NaN is unordered/unspecified in the + /// encoder; -0.0 canonicalizes to +0.0 and would duplicate the +0.0 row. + /// ±Inf MUST be present (the boundary pivots). + #[test] + fn float_fixtures_exclude_nan_and_negative_zero_and_include_infinities() { + for token in ["float4", "float8"] { + let s = scalar(token); + let strings: Vec<&str> = s + .fixtures + .iter() + .map(|f| match f { + Fixture::Float(v) => *v, + other => panic!("{token} fixture must be Fixture::Float, got {other:?}"), + }) + .collect(); + for v in &strings { + let parsed: f64 = v + .parse() + .unwrap_or_else(|_| panic!("{token} fixture {v:?} must parse as f64")); + assert!(!parsed.is_nan(), "{token} fixture {v:?} is NaN"); + assert!( + !(parsed == 0.0 && parsed.is_sign_negative()), + "{token} fixture {v:?} is -0.0" + ); + } + assert!(strings.contains(&"inf"), "{token} must include +inf pivot"); + assert!(strings.contains(&"-inf"), "{token} must include -inf pivot"); + assert!(strings.contains(&"0"), "{token} must include 0 (origin)"); + } + } + + /// Distinct by parsed f64 value (the catalog dedupes only by literal string; + /// the fixture table keys on the value, so an aliasing pair would break + /// fetch_fixture_payload's fetch_one). + #[test] + fn float_fixtures_are_distinct_by_value() { + for token in ["float4", "float8"] { + let s = scalar(token); + let parsed: Vec = s + .fixtures + .iter() + .map(|f| match f { + Fixture::Float(v) => { + let x: f64 = v.parse().unwrap(); + // total_cmp bit key; -0.0 already excluded so +0.0 is unique. + x.to_bits() + } + other => panic!("non-float fixture: {other:?}"), + }) + .collect(); + let mut sorted = parsed.clone(); + sorted.sort_unstable(); + sorted.dedup(); + assert_eq!(sorted.len(), parsed.len(), "{token} has duplicate fixtures"); + } + } +} + mod invariant_tests { use crate::*; use std::collections::HashMap; @@ -936,7 +1042,11 @@ mod invariant_tests { | Fixture::Text(s) | Fixture::Jsonb(s) | Fixture::Date(s) - | Fixture::Timestamptz(s) => DistinctKey::Str(s), + | Fixture::Timestamptz(s) + // Float fixtures dedupe by their literal here, like the other + // string-backed kinds (every float literal is distinct; the harness + // `float_fixtures_are_distinct_by_value` guard pins value-distinctness). + | Fixture::Float(s) => DistinctKey::Str(s), // `bool` is storage-only and string-backed for distinctness: the two // values dedupe by their literal, like the other non-numeric kinds. Fixture::Bool(b) => DistinctKey::Str(if b { "true" } else { "false" }), diff --git a/tests/codegen/reference/float4/float4_eq_functions.sql b/tests/codegen/reference/float4/float4_eq_functions.sql new file mode 100644 index 00000000..faf8b30f --- /dev/null +++ b/tests/codegen/reference/float4/float4_eq_functions.sql @@ -0,0 +1,407 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/hmac_256/functions.sql + +--! @file encrypted_domain/float4/float4_eq_functions.sql +--! @brief Functions for eql_v3.float4_eq. + +--! @brief Index extractor for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @return eql_v3.hmac_256 +CREATE FUNCTION eql_v3.eq_term(a eql_v3.float4_eq) +RETURNS eql_v3.hmac_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.hmac_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) = eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_eq, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) = eql_v3.eq_term(b::eql_v3.float4_eq) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float4_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a::eql_v3.float4_eq) = eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) <> eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_eq, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) <> eql_v3.eq_term(b::eql_v3.float4_eq) $$; + +--! @brief Operator wrapper for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float4_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a::eql_v3.float4_eq) <> eql_v3.eq_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float4_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param selector text +--! @return eql_v3.float4_eq +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_eq, selector text) +RETURNS eql_v3.float4_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param selector integer +--! @return eql_v3.float4_eq +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_eq, selector integer) +RETURNS eql_v3.float4_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param selector eql_v3.float4_eq +--! @return eql_v3.float4_eq +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float4_eq) +RETURNS eql_v3.float4_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_eq, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_eq, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param selector eql_v3.float4_eq +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float4_eq) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float4_eq, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float4_eq, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float4_eq, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float4_eq, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float4_eq, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float4_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float4_eq, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_eq, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_eq, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float4_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b eql_v3.float4_eq +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_eq, b eql_v3.float4_eq) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a eql_v3.float4_eq +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_eq, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_eq. +--! @param a jsonb +--! @param b eql_v3.float4_eq +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float4_eq) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_eq'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float4/float4_eq_operators.sql b/tests/codegen/reference/float4/float4_eq_operators.sql new file mode 100644 index 00000000..b86f7f5e --- /dev/null +++ b/tests/codegen/reference/float4/float4_eq_operators.sql @@ -0,0 +1,234 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_eq_functions.sql + +--! @file encrypted_domain/float4/float4_eq_operators.sql +--! @brief Operators for eql_v3.float4_eq. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_eq, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_eq, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_eq, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float4_eq, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_eq, RIGHTARG = eql_v3.float4_eq +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_eq +); diff --git a/tests/codegen/reference/float4/float4_functions.sql b/tests/codegen/reference/float4/float4_functions.sql new file mode 100644 index 00000000..f444a4b7 --- /dev/null +++ b/tests/codegen/reference/float4/float4_functions.sql @@ -0,0 +1,404 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/functions.sql + +--! @file encrypted_domain/float4/float4_functions.sql +--! @brief Functions for eql_v3.float4. + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float4) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param selector text +--! @return eql_v3.float4 +CREATE FUNCTION eql_v3."->"(a eql_v3.float4, selector text) +RETURNS eql_v3.float4 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param selector integer +--! @return eql_v3.float4 +CREATE FUNCTION eql_v3."->"(a eql_v3.float4, selector integer) +RETURNS eql_v3.float4 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param selector eql_v3.float4 +--! @return eql_v3.float4 +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float4) +RETURNS eql_v3.float4 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param selector eql_v3.float4 +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float4) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float4, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float4, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float4, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float4, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float4, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float4, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float4, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float4, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b eql_v3.float4 +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4, b eql_v3.float4) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a eql_v3.float4 +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4. +--! @param a jsonb +--! @param b eql_v3.float4 +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float4) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float4/float4_operators.sql b/tests/codegen/reference/float4/float4_operators.sql new file mode 100644 index 00000000..fed4f8c4 --- /dev/null +++ b/tests/codegen/reference/float4/float4_operators.sql @@ -0,0 +1,228 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_functions.sql + +--! @file encrypted_domain/float4/float4_operators.sql +--! @brief Operators for eql_v3.float4. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float4, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float4, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float4, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float4, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4, RIGHTARG = eql_v3.float4 +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4 +); diff --git a/tests/codegen/reference/float4/float4_ord_aggregates.sql b/tests/codegen/reference/float4/float4_ord_aggregates.sql new file mode 100644 index 00000000..45eab28a --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_aggregates.sql @@ -0,0 +1,63 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_functions.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_operators.sql + +--! @file encrypted_domain/float4/float4_ord_aggregates.sql +--! @brief Aggregates for eql_v3.float4_ord. + +--! @brief State function for min on eql_v3.float4_ord. +--! @param state eql_v3.float4_ord +--! @param value eql_v3.float4_ord +--! @return eql_v3.float4_ord +CREATE FUNCTION eql_v3.min_sfunc(state eql_v3.float4_ord, value eql_v3.float4_ord) +RETURNS eql_v3.float4_ord +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value < state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief min aggregate for eql_v3.float4_ord. +--! @param input eql_v3.float4_ord +--! @return eql_v3.float4_ord +CREATE AGGREGATE eql_v3.min(eql_v3.float4_ord) ( + sfunc = eql_v3.min_sfunc, + stype = eql_v3.float4_ord, + combinefunc = eql_v3.min_sfunc, + parallel = safe +); + +--! @brief State function for max on eql_v3.float4_ord. +--! @param state eql_v3.float4_ord +--! @param value eql_v3.float4_ord +--! @return eql_v3.float4_ord +CREATE FUNCTION eql_v3.max_sfunc(state eql_v3.float4_ord, value eql_v3.float4_ord) +RETURNS eql_v3.float4_ord +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value > state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief max aggregate for eql_v3.float4_ord. +--! @param input eql_v3.float4_ord +--! @return eql_v3.float4_ord +CREATE AGGREGATE eql_v3.max(eql_v3.float4_ord) ( + sfunc = eql_v3.max_sfunc, + stype = eql_v3.float4_ord, + combinefunc = eql_v3.max_sfunc, + parallel = safe +); diff --git a/tests/codegen/reference/float4/float4_ord_functions.sql b/tests/codegen/reference/float4/float4_ord_functions.sql new file mode 100644 index 00000000..b036db6c --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_functions.sql @@ -0,0 +1,396 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/operators.sql + +--! @file encrypted_domain/float4/float4_ord_functions.sql +--! @brief Functions for eql_v3.float4_ord. + +--! @brief Index extractor for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @return eql_v3.ore_block_256 +CREATE FUNCTION eql_v3.ord_term(a eql_v3.float4_ord) +RETURNS eql_v3.ore_block_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ore_block_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b::eql_v3.float4_ord) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float4_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord) >= eql_v3.ord_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_ord, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float4_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_ord, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float4_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param selector text +--! @return eql_v3.float4_ord +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_ord, selector text) +RETURNS eql_v3.float4_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param selector integer +--! @return eql_v3.float4_ord +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_ord, selector integer) +RETURNS eql_v3.float4_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a jsonb +--! @param selector eql_v3.float4_ord +--! @return eql_v3.float4_ord +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float4_ord) +RETURNS eql_v3.float4_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_ord, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_ord, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a jsonb +--! @param selector eql_v3.float4_ord +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float4_ord) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float4_ord, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float4_ord, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float4_ord, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float4_ord, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float4_ord, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float4_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float4_ord, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float4_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b eql_v3.float4_ord +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_ord, b eql_v3.float4_ord) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a eql_v3.float4_ord +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_ord, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord. +--! @param a jsonb +--! @param b eql_v3.float4_ord +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float4_ord) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float4/float4_ord_operators.sql b/tests/codegen/reference/float4/float4_ord_operators.sql new file mode 100644 index 00000000..15159578 --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_operators.sql @@ -0,0 +1,246 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_functions.sql + +--! @file encrypted_domain/float4/float4_ord_operators.sql +--! @brief Operators for eql_v3.float4_ord. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_ord, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_ord, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float4_ord, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_ord, RIGHTARG = eql_v3.float4_ord +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord +); diff --git a/tests/codegen/reference/float4/float4_ord_ore_aggregates.sql b/tests/codegen/reference/float4/float4_ord_ore_aggregates.sql new file mode 100644 index 00000000..5ec53ecc --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_ore_aggregates.sql @@ -0,0 +1,63 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_ore_functions.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_ore_operators.sql + +--! @file encrypted_domain/float4/float4_ord_ore_aggregates.sql +--! @brief Aggregates for eql_v3.float4_ord_ore. + +--! @brief State function for min on eql_v3.float4_ord_ore. +--! @param state eql_v3.float4_ord_ore +--! @param value eql_v3.float4_ord_ore +--! @return eql_v3.float4_ord_ore +CREATE FUNCTION eql_v3.min_sfunc(state eql_v3.float4_ord_ore, value eql_v3.float4_ord_ore) +RETURNS eql_v3.float4_ord_ore +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value < state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief min aggregate for eql_v3.float4_ord_ore. +--! @param input eql_v3.float4_ord_ore +--! @return eql_v3.float4_ord_ore +CREATE AGGREGATE eql_v3.min(eql_v3.float4_ord_ore) ( + sfunc = eql_v3.min_sfunc, + stype = eql_v3.float4_ord_ore, + combinefunc = eql_v3.min_sfunc, + parallel = safe +); + +--! @brief State function for max on eql_v3.float4_ord_ore. +--! @param state eql_v3.float4_ord_ore +--! @param value eql_v3.float4_ord_ore +--! @return eql_v3.float4_ord_ore +CREATE FUNCTION eql_v3.max_sfunc(state eql_v3.float4_ord_ore, value eql_v3.float4_ord_ore) +RETURNS eql_v3.float4_ord_ore +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value > state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief max aggregate for eql_v3.float4_ord_ore. +--! @param input eql_v3.float4_ord_ore +--! @return eql_v3.float4_ord_ore +CREATE AGGREGATE eql_v3.max(eql_v3.float4_ord_ore) ( + sfunc = eql_v3.max_sfunc, + stype = eql_v3.float4_ord_ore, + combinefunc = eql_v3.max_sfunc, + parallel = safe +); diff --git a/tests/codegen/reference/float4/float4_ord_ore_functions.sql b/tests/codegen/reference/float4/float4_ord_ore_functions.sql new file mode 100644 index 00000000..b2edffc7 --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_ore_functions.sql @@ -0,0 +1,396 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/operators.sql + +--! @file encrypted_domain/float4/float4_ord_ore_functions.sql +--! @brief Functions for eql_v3.float4_ord_ore. + +--! @brief Index extractor for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @return eql_v3.ore_block_256 +CREATE FUNCTION eql_v3.ord_term(a eql_v3.float4_ord_ore) +RETURNS eql_v3.ore_block_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ore_block_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b::eql_v3.float4_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float4_ord_ore) >= eql_v3.ord_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float4_ord_ore, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float4_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param selector text +--! @return eql_v3.float4_ord_ore +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_ord_ore, selector text) +RETURNS eql_v3.float4_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param selector integer +--! @return eql_v3.float4_ord_ore +CREATE FUNCTION eql_v3."->"(a eql_v3.float4_ord_ore, selector integer) +RETURNS eql_v3.float4_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param selector eql_v3.float4_ord_ore +--! @return eql_v3.float4_ord_ore +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float4_ord_ore) +RETURNS eql_v3.float4_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_ord_ore, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float4_ord_ore, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param selector eql_v3.float4_ord_ore +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float4_ord_ore) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float4_ord_ore, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float4_ord_ore, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float4_ord_ore, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float4_ord_ore, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float4_ord_ore, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float4_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float4_ord_ore, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord_ore, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord_ore, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float4_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float4_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b eql_v3.float4_ord_ore +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_ord_ore, b eql_v3.float4_ord_ore) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a eql_v3.float4_ord_ore +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float4_ord_ore, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float4_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float4_ord_ore +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float4_ord_ore) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float4_ord_ore'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float4/float4_ord_ore_operators.sql b/tests/codegen/reference/float4/float4_ord_ore_operators.sql new file mode 100644 index 00000000..b3e4f87e --- /dev/null +++ b/tests/codegen/reference/float4/float4_ord_ore_operators.sql @@ -0,0 +1,246 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float4/float4_types.sql +-- REQUIRE: src/v3/scalars/float4/float4_ord_ore_functions.sql + +--! @file encrypted_domain/float4/float4_ord_ore_operators.sql +--! @brief Operators for eql_v3.float4_ord_ore. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = eql_v3.float4_ord_ore +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float4_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float4_ord_ore +); diff --git a/tests/codegen/reference/float4/float4_types.sql b/tests/codegen/reference/float4/float4_types.sql new file mode 100644 index 00000000..56ef6e7b --- /dev/null +++ b/tests/codegen/reference/float4/float4_types.sql @@ -0,0 +1,73 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql + +--! @file v3/scalars/float4/float4_types.sql +--! @brief Encrypted-domain types for float4. + +DO $$ +BEGIN + --! @brief Encrypted domain eql_v3.float4. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float4' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float4 AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float4_eq. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float4_eq' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float4_eq AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'hm' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float4_ord_ore. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float4_ord_ore' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float4_ord_ore AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'ob' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float4_ord. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float4_ord' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float4_ord AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'ob' + AND VALUE->>'v' = '2' + ); + END IF; +END +$$; diff --git a/tests/codegen/reference/float8/float8_eq_functions.sql b/tests/codegen/reference/float8/float8_eq_functions.sql new file mode 100644 index 00000000..a5d592cf --- /dev/null +++ b/tests/codegen/reference/float8/float8_eq_functions.sql @@ -0,0 +1,407 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/hmac_256/functions.sql + +--! @file encrypted_domain/float8/float8_eq_functions.sql +--! @brief Functions for eql_v3.float8_eq. + +--! @brief Index extractor for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @return eql_v3.hmac_256 +CREATE FUNCTION eql_v3.eq_term(a eql_v3.float8_eq) +RETURNS eql_v3.hmac_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.hmac_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) = eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_eq, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) = eql_v3.eq_term(b::eql_v3.float8_eq) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float8_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a::eql_v3.float8_eq) = eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) <> eql_v3.eq_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_eq, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a) <> eql_v3.eq_term(b::eql_v3.float8_eq) $$; + +--! @brief Operator wrapper for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float8_eq) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.eq_term(a::eql_v3.float8_eq) <> eql_v3.eq_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_eq, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float8_eq) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param selector text +--! @return eql_v3.float8_eq +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_eq, selector text) +RETURNS eql_v3.float8_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param selector integer +--! @return eql_v3.float8_eq +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_eq, selector integer) +RETURNS eql_v3.float8_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param selector eql_v3.float8_eq +--! @return eql_v3.float8_eq +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float8_eq) +RETURNS eql_v3.float8_eq IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_eq, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_eq, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param selector eql_v3.float8_eq +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float8_eq) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float8_eq, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float8_eq, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float8_eq, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float8_eq, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float8_eq, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float8_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float8_eq, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_eq, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_eq, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float8_eq, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b eql_v3.float8_eq +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_eq, b eql_v3.float8_eq) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a eql_v3.float8_eq +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_eq, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_eq. +--! @param a jsonb +--! @param b eql_v3.float8_eq +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float8_eq) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_eq'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float8/float8_eq_operators.sql b/tests/codegen/reference/float8/float8_eq_operators.sql new file mode 100644 index 00000000..83f8cf27 --- /dev/null +++ b/tests/codegen/reference/float8/float8_eq_operators.sql @@ -0,0 +1,234 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_eq_functions.sql + +--! @file encrypted_domain/float8/float8_eq_operators.sql +--! @brief Operators for eql_v3.float8_eq. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_eq, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_eq, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_eq, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float8_eq, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_eq, RIGHTARG = eql_v3.float8_eq +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_eq, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_eq +); diff --git a/tests/codegen/reference/float8/float8_functions.sql b/tests/codegen/reference/float8/float8_functions.sql new file mode 100644 index 00000000..cc6c50f8 --- /dev/null +++ b/tests/codegen/reference/float8/float8_functions.sql @@ -0,0 +1,404 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/functions.sql + +--! @file encrypted_domain/float8/float8_functions.sql +--! @brief Functions for eql_v3.float8. + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '>=', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float8) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param selector text +--! @return eql_v3.float8 +CREATE FUNCTION eql_v3."->"(a eql_v3.float8, selector text) +RETURNS eql_v3.float8 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param selector integer +--! @return eql_v3.float8 +CREATE FUNCTION eql_v3."->"(a eql_v3.float8, selector integer) +RETURNS eql_v3.float8 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param selector eql_v3.float8 +--! @return eql_v3.float8 +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float8) +RETURNS eql_v3.float8 IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param selector eql_v3.float8 +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float8) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float8, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float8, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float8, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float8, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float8, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float8, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float8, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float8, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b eql_v3.float8 +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8, b eql_v3.float8) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a eql_v3.float8 +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8. +--! @param a jsonb +--! @param b eql_v3.float8 +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float8) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float8/float8_operators.sql b/tests/codegen/reference/float8/float8_operators.sql new file mode 100644 index 00000000..472b9095 --- /dev/null +++ b/tests/codegen/reference/float8/float8_operators.sql @@ -0,0 +1,228 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_functions.sql + +--! @file encrypted_domain/float8/float8_operators.sql +--! @brief Operators for eql_v3.float8. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float8, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float8, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float8, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float8, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8, RIGHTARG = eql_v3.float8 +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8 +); diff --git a/tests/codegen/reference/float8/float8_ord_aggregates.sql b/tests/codegen/reference/float8/float8_ord_aggregates.sql new file mode 100644 index 00000000..64bd7f47 --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_aggregates.sql @@ -0,0 +1,63 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_functions.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_operators.sql + +--! @file encrypted_domain/float8/float8_ord_aggregates.sql +--! @brief Aggregates for eql_v3.float8_ord. + +--! @brief State function for min on eql_v3.float8_ord. +--! @param state eql_v3.float8_ord +--! @param value eql_v3.float8_ord +--! @return eql_v3.float8_ord +CREATE FUNCTION eql_v3.min_sfunc(state eql_v3.float8_ord, value eql_v3.float8_ord) +RETURNS eql_v3.float8_ord +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value < state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief min aggregate for eql_v3.float8_ord. +--! @param input eql_v3.float8_ord +--! @return eql_v3.float8_ord +CREATE AGGREGATE eql_v3.min(eql_v3.float8_ord) ( + sfunc = eql_v3.min_sfunc, + stype = eql_v3.float8_ord, + combinefunc = eql_v3.min_sfunc, + parallel = safe +); + +--! @brief State function for max on eql_v3.float8_ord. +--! @param state eql_v3.float8_ord +--! @param value eql_v3.float8_ord +--! @return eql_v3.float8_ord +CREATE FUNCTION eql_v3.max_sfunc(state eql_v3.float8_ord, value eql_v3.float8_ord) +RETURNS eql_v3.float8_ord +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value > state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief max aggregate for eql_v3.float8_ord. +--! @param input eql_v3.float8_ord +--! @return eql_v3.float8_ord +CREATE AGGREGATE eql_v3.max(eql_v3.float8_ord) ( + sfunc = eql_v3.max_sfunc, + stype = eql_v3.float8_ord, + combinefunc = eql_v3.max_sfunc, + parallel = safe +); diff --git a/tests/codegen/reference/float8/float8_ord_functions.sql b/tests/codegen/reference/float8/float8_ord_functions.sql new file mode 100644 index 00000000..0591e66c --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_functions.sql @@ -0,0 +1,396 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/operators.sql + +--! @file encrypted_domain/float8/float8_ord_functions.sql +--! @brief Functions for eql_v3.float8_ord. + +--! @brief Index extractor for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @return eql_v3.ore_block_256 +CREATE FUNCTION eql_v3.ord_term(a eql_v3.float8_ord) +RETURNS eql_v3.ore_block_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ore_block_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_ord, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b::eql_v3.float8_ord) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float8_ord) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord) >= eql_v3.ord_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_ord, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float8_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_ord, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float8_ord) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param selector text +--! @return eql_v3.float8_ord +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_ord, selector text) +RETURNS eql_v3.float8_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param selector integer +--! @return eql_v3.float8_ord +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_ord, selector integer) +RETURNS eql_v3.float8_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a jsonb +--! @param selector eql_v3.float8_ord +--! @return eql_v3.float8_ord +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float8_ord) +RETURNS eql_v3.float8_ord IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_ord, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_ord, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a jsonb +--! @param selector eql_v3.float8_ord +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float8_ord) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float8_ord, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float8_ord, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float8_ord, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float8_ord, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float8_ord, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float8_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float8_ord, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float8_ord, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b eql_v3.float8_ord +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_ord, b eql_v3.float8_ord) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a eql_v3.float8_ord +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_ord, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord. +--! @param a jsonb +--! @param b eql_v3.float8_ord +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float8_ord) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float8/float8_ord_operators.sql b/tests/codegen/reference/float8/float8_ord_operators.sql new file mode 100644 index 00000000..86e04b34 --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_operators.sql @@ -0,0 +1,246 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_functions.sql + +--! @file encrypted_domain/float8/float8_ord_operators.sql +--! @brief Operators for eql_v3.float8_ord. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_ord, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_ord, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float8_ord, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_ord, RIGHTARG = eql_v3.float8_ord +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_ord, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord +); diff --git a/tests/codegen/reference/float8/float8_ord_ore_aggregates.sql b/tests/codegen/reference/float8/float8_ord_ore_aggregates.sql new file mode 100644 index 00000000..81620108 --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_ore_aggregates.sql @@ -0,0 +1,63 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_ore_functions.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_ore_operators.sql + +--! @file encrypted_domain/float8/float8_ord_ore_aggregates.sql +--! @brief Aggregates for eql_v3.float8_ord_ore. + +--! @brief State function for min on eql_v3.float8_ord_ore. +--! @param state eql_v3.float8_ord_ore +--! @param value eql_v3.float8_ord_ore +--! @return eql_v3.float8_ord_ore +CREATE FUNCTION eql_v3.min_sfunc(state eql_v3.float8_ord_ore, value eql_v3.float8_ord_ore) +RETURNS eql_v3.float8_ord_ore +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value < state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief min aggregate for eql_v3.float8_ord_ore. +--! @param input eql_v3.float8_ord_ore +--! @return eql_v3.float8_ord_ore +CREATE AGGREGATE eql_v3.min(eql_v3.float8_ord_ore) ( + sfunc = eql_v3.min_sfunc, + stype = eql_v3.float8_ord_ore, + combinefunc = eql_v3.min_sfunc, + parallel = safe +); + +--! @brief State function for max on eql_v3.float8_ord_ore. +--! @param state eql_v3.float8_ord_ore +--! @param value eql_v3.float8_ord_ore +--! @return eql_v3.float8_ord_ore +CREATE FUNCTION eql_v3.max_sfunc(state eql_v3.float8_ord_ore, value eql_v3.float8_ord_ore) +RETURNS eql_v3.float8_ord_ore +LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE +SET search_path = pg_catalog, extensions, public +AS $$ +BEGIN + IF value > state THEN + RETURN value; + END IF; + RETURN state; +END; +$$; + +--! @brief max aggregate for eql_v3.float8_ord_ore. +--! @param input eql_v3.float8_ord_ore +--! @return eql_v3.float8_ord_ore +CREATE AGGREGATE eql_v3.max(eql_v3.float8_ord_ore) ( + sfunc = eql_v3.max_sfunc, + stype = eql_v3.float8_ord_ore, + combinefunc = eql_v3.max_sfunc, + parallel = safe +); diff --git a/tests/codegen/reference/float8/float8_ord_ore_functions.sql b/tests/codegen/reference/float8/float8_ord_ore_functions.sql new file mode 100644 index 00000000..4ba85671 --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_ore_functions.sql @@ -0,0 +1,396 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/functions.sql +-- REQUIRE: src/v3/sem/ore_block_256/operators.sql + +--! @file encrypted_domain/float8/float8_ord_ore_functions.sql +--! @brief Functions for eql_v3.float8_ord_ore. + +--! @brief Index extractor for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @return eql_v3.ore_block_256 +CREATE FUNCTION eql_v3.ord_term(a eql_v3.float8_ord_ore) +RETURNS eql_v3.ore_block_256 +LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ore_block_256(a::jsonb) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.eq(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) = eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.eq(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) = eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.neq(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <> eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.neq(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) <> eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lt(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) < eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lt(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) < eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.lte(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) <= eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.lte(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) <= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gt(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) > eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gt(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) > eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.gte(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a) >= eql_v3.ord_term(b::eql_v3.float8_ord_ore) $$; + +--! @brief Operator wrapper for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.gte(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE +AS $$ SELECT eql_v3.ord_term(a::eql_v3.float8_ord_ore) >= eql_v3.ord_term(b) $$; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contains(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contains(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a eql_v3.float8_ord_ore, b jsonb) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return boolean +CREATE FUNCTION eql_v3.contained_by(a jsonb, b eql_v3.float8_ord_ore) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '<@', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param selector text +--! @return eql_v3.float8_ord_ore +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_ord_ore, selector text) +RETURNS eql_v3.float8_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param selector integer +--! @return eql_v3.float8_ord_ore +CREATE FUNCTION eql_v3."->"(a eql_v3.float8_ord_ore, selector integer) +RETURNS eql_v3.float8_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param selector eql_v3.float8_ord_ore +--! @return eql_v3.float8_ord_ore +CREATE FUNCTION eql_v3."->"(a jsonb, selector eql_v3.float8_ord_ore) +RETURNS eql_v3.float8_ord_ore IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param selector text +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_ord_ore, selector text) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param selector integer +--! @return text +CREATE FUNCTION eql_v3."->>"(a eql_v3.float8_ord_ore, selector integer) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param selector eql_v3.float8_ord_ore +--! @return text +CREATE FUNCTION eql_v3."->>"(a jsonb, selector eql_v3.float8_ord_ore) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '->>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text +--! @return boolean +CREATE FUNCTION eql_v3."?"(a eql_v3.float8_ord_ore, b text) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?|"(a eql_v3.float8_ord_ore, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?|', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return boolean +CREATE FUNCTION eql_v3."?&"(a eql_v3.float8_ord_ore, b text[]) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '?&', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@?"(a eql_v3.float8_ord_ore, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@?', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonpath +--! @return boolean +CREATE FUNCTION eql_v3."@@"(a eql_v3.float8_ord_ore, b jsonpath) +RETURNS boolean IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '@@', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#>"(a eql_v3.float8_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return text +CREATE FUNCTION eql_v3."#>>"(a eql_v3.float8_ord_ore, b text[]) +RETURNS text IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#>>', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord_ore, b text) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b integer +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord_ore, b integer) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."-"(a eql_v3.float8_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '-', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b text[] +--! @return jsonb +CREATE FUNCTION eql_v3."#-"(a eql_v3.float8_ord_ore, b text[]) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '#-', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b eql_v3.float8_ord_ore +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_ord_ore, b eql_v3.float8_ord_ore) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a eql_v3.float8_ord_ore +--! @param b jsonb +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a eql_v3.float8_ord_ore, b jsonb) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; + +--! @brief Unsupported operator blocker for eql_v3.float8_ord_ore. +--! @param a jsonb +--! @param b eql_v3.float8_ord_ore +--! @return jsonb +CREATE FUNCTION eql_v3."||"(a jsonb, b eql_v3.float8_ord_ore) +RETURNS jsonb IMMUTABLE PARALLEL SAFE +AS $$ BEGIN RAISE EXCEPTION 'operator % is not supported for %', '||', 'eql_v3.float8_ord_ore'; END; $$ +LANGUAGE plpgsql; diff --git a/tests/codegen/reference/float8/float8_ord_ore_operators.sql b/tests/codegen/reference/float8/float8_ord_ore_operators.sql new file mode 100644 index 00000000..f4a63f61 --- /dev/null +++ b/tests/codegen/reference/float8/float8_ord_ore_operators.sql @@ -0,0 +1,246 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql +-- REQUIRE: src/v3/scalars/float8/float8_types.sql +-- REQUIRE: src/v3/scalars/float8/float8_ord_ore_functions.sql + +--! @file encrypted_domain/float8/float8_ord_ore_operators.sql +--! @brief Operators for eql_v3.float8_ord_ore. + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR = ( + FUNCTION = eql_v3.eq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = =, NEGATOR = <>, RESTRICT = eqsel, JOIN = eqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR <> ( + FUNCTION = eql_v3.neq, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <>, NEGATOR = =, RESTRICT = neqsel, JOIN = neqjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR < ( + FUNCTION = eql_v3.lt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = >, NEGATOR = >=, RESTRICT = scalarltsel, JOIN = scalarltjoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR <= ( + FUNCTION = eql_v3.lte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = >=, NEGATOR = >, RESTRICT = scalarlesel, JOIN = scalarlejoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR > ( + FUNCTION = eql_v3.gt, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <, NEGATOR = <=, RESTRICT = scalargtsel, JOIN = scalargtjoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR >= ( + FUNCTION = eql_v3.gte, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore, + COMMUTATOR = <=, NEGATOR = <, RESTRICT = scalargesel, JOIN = scalargejoinsel +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR @> ( + FUNCTION = eql_v3.contains, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR <@ ( + FUNCTION = eql_v3.contained_by, + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR -> ( + FUNCTION = eql_v3."->", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR ->> ( + FUNCTION = eql_v3."->>", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR ? ( + FUNCTION = eql_v3."?", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR ?| ( + FUNCTION = eql_v3."?|", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR ?& ( + FUNCTION = eql_v3."?&", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR @? ( + FUNCTION = eql_v3."@?", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonpath +); + +CREATE OPERATOR @@ ( + FUNCTION = eql_v3."@@", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonpath +); + +CREATE OPERATOR #> ( + FUNCTION = eql_v3."#>", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR #>> ( + FUNCTION = eql_v3."#>>", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = integer +); + +CREATE OPERATOR - ( + FUNCTION = eql_v3."-", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR #- ( + FUNCTION = eql_v3."#-", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = text[] +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = eql_v3.float8_ord_ore +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = eql_v3.float8_ord_ore, RIGHTARG = jsonb +); + +CREATE OPERATOR || ( + FUNCTION = eql_v3."||", + LEFTARG = jsonb, RIGHTARG = eql_v3.float8_ord_ore +); diff --git a/tests/codegen/reference/float8/float8_types.sql b/tests/codegen/reference/float8/float8_types.sql new file mode 100644 index 00000000..8ff718e5 --- /dev/null +++ b/tests/codegen/reference/float8/float8_types.sql @@ -0,0 +1,73 @@ +-- REFERENCE: hand-maintained parity baseline for crates/eql-codegen - see ../README.md +-- AUTOMATICALLY GENERATED FILE. +-- REQUIRE: src/v3/schema.sql + +--! @file v3/scalars/float8/float8_types.sql +--! @brief Encrypted-domain types for float8. + +DO $$ +BEGIN + --! @brief Encrypted domain eql_v3.float8. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float8' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float8 AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float8_eq. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float8_eq' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float8_eq AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'hm' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float8_ord_ore. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float8_ord_ore' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float8_ord_ore AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'ob' + AND VALUE->>'v' = '2' + ); + END IF; + + --! @brief Encrypted domain eql_v3.float8_ord. + IF NOT EXISTS ( + SELECT 1 FROM pg_type + WHERE typname = 'float8_ord' AND typnamespace = 'eql_v3'::regnamespace + ) THEN + CREATE DOMAIN eql_v3.float8_ord AS jsonb + CHECK ( + jsonb_typeof(VALUE) = 'object' + AND VALUE ? 'v' + AND VALUE ? 'i' + AND VALUE ? 'c' + AND VALUE ? 'ob' + AND VALUE->>'v' = '2' + ); + END IF; +END +$$; From 62fdc0a1a2d3adce8b82695b1b91d6add43bf36b Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 20:06:29 +1000 Subject: [PATCH 2/6] feat(v3): eql-types float4/float8 payload types + bindings/schemas float4/float8 v3 domain payload types in eql-types, with the generated TypeScript bindings and JSON Schemas for each domain variant. --- crates/eql-types/bindings/v3/Float4.ts | 22 +++ crates/eql-types/bindings/v3/Float4Eq.ts | 27 ++++ crates/eql-types/bindings/v3/Float4Ord.ts | 27 ++++ crates/eql-types/bindings/v3/Float4OrdOre.ts | 27 ++++ crates/eql-types/bindings/v3/Float8.ts | 22 +++ crates/eql-types/bindings/v3/Float8Eq.ts | 27 ++++ crates/eql-types/bindings/v3/Float8Ord.ts | 27 ++++ crates/eql-types/bindings/v3/Float8OrdOre.ts | 27 ++++ crates/eql-types/schema/v3/float4.json | 69 +++++++++ crates/eql-types/schema/v3/float4_eq.json | 82 +++++++++++ crates/eql-types/schema/v3/float4_ord.json | 85 +++++++++++ .../eql-types/schema/v3/float4_ord_ore.json | 85 +++++++++++ crates/eql-types/schema/v3/float8.json | 69 +++++++++ crates/eql-types/schema/v3/float8_eq.json | 82 +++++++++++ crates/eql-types/schema/v3/float8_ord.json | 85 +++++++++++ .../eql-types/schema/v3/float8_ord_ore.json | 85 +++++++++++ crates/eql-types/src/v3/float4.rs | 137 ++++++++++++++++++ crates/eql-types/src/v3/float8.rs | 136 +++++++++++++++++ crates/eql-types/src/v3/mod.rs | 10 ++ 19 files changed, 1131 insertions(+) create mode 100644 crates/eql-types/bindings/v3/Float4.ts create mode 100644 crates/eql-types/bindings/v3/Float4Eq.ts create mode 100644 crates/eql-types/bindings/v3/Float4Ord.ts create mode 100644 crates/eql-types/bindings/v3/Float4OrdOre.ts create mode 100644 crates/eql-types/bindings/v3/Float8.ts create mode 100644 crates/eql-types/bindings/v3/Float8Eq.ts create mode 100644 crates/eql-types/bindings/v3/Float8Ord.ts create mode 100644 crates/eql-types/bindings/v3/Float8OrdOre.ts create mode 100644 crates/eql-types/schema/v3/float4.json create mode 100644 crates/eql-types/schema/v3/float4_eq.json create mode 100644 crates/eql-types/schema/v3/float4_ord.json create mode 100644 crates/eql-types/schema/v3/float4_ord_ore.json create mode 100644 crates/eql-types/schema/v3/float8.json create mode 100644 crates/eql-types/schema/v3/float8_eq.json create mode 100644 crates/eql-types/schema/v3/float8_ord.json create mode 100644 crates/eql-types/schema/v3/float8_ord_ore.json create mode 100644 crates/eql-types/src/v3/float4.rs create mode 100644 crates/eql-types/src/v3/float8.rs diff --git a/crates/eql-types/bindings/v3/Float4.ts b/crates/eql-types/bindings/v3/Float4.ts new file mode 100644 index 00000000..73752d78 --- /dev/null +++ b/crates/eql-types/bindings/v3/Float4.ts @@ -0,0 +1,22 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float4` — storage only; every operator is blocked. + */ +export type Float4 = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, }; diff --git a/crates/eql-types/bindings/v3/Float4Eq.ts b/crates/eql-types/bindings/v3/Float4Eq.ts new file mode 100644 index 00000000..d734162b --- /dev/null +++ b/crates/eql-types/bindings/v3/Float4Eq.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Hmac256 } from "./Hmac256"; +import type { Identifier } from "./Identifier"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float4_eq` — HMAC equality (`=`, `<>`). + */ +export type Float4Eq = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * HMAC-SHA-256 equality term. + */ +hm: Hmac256, }; diff --git a/crates/eql-types/bindings/v3/Float4Ord.ts b/crates/eql-types/bindings/v3/Float4Ord.ts new file mode 100644 index 00000000..658564a0 --- /dev/null +++ b/crates/eql-types/bindings/v3/Float4Ord.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { OreBlock256 } from "./OreBlock256"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float4_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`). + */ +export type Float4Ord = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * Block-ORE order term (8 blocks for float). Serves equality too. + */ +ob: OreBlock256, }; diff --git a/crates/eql-types/bindings/v3/Float4OrdOre.ts b/crates/eql-types/bindings/v3/Float4OrdOre.ts new file mode 100644 index 00000000..9daebc7c --- /dev/null +++ b/crates/eql-types/bindings/v3/Float4OrdOre.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { OreBlock256 } from "./OreBlock256"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float4_ord_ore` — full comparison, scheme-explicit name. + */ +export type Float4OrdOre = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * Block-ORE order term (8 blocks for float). Serves equality too. + */ +ob: OreBlock256, }; diff --git a/crates/eql-types/bindings/v3/Float8.ts b/crates/eql-types/bindings/v3/Float8.ts new file mode 100644 index 00000000..71f064d6 --- /dev/null +++ b/crates/eql-types/bindings/v3/Float8.ts @@ -0,0 +1,22 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float8` — storage only; every operator is blocked. + */ +export type Float8 = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, }; diff --git a/crates/eql-types/bindings/v3/Float8Eq.ts b/crates/eql-types/bindings/v3/Float8Eq.ts new file mode 100644 index 00000000..21714637 --- /dev/null +++ b/crates/eql-types/bindings/v3/Float8Eq.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Hmac256 } from "./Hmac256"; +import type { Identifier } from "./Identifier"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float8_eq` — HMAC equality (`=`, `<>`). + */ +export type Float8Eq = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * HMAC-SHA-256 equality term. + */ +hm: Hmac256, }; diff --git a/crates/eql-types/bindings/v3/Float8Ord.ts b/crates/eql-types/bindings/v3/Float8Ord.ts new file mode 100644 index 00000000..209b1c2e --- /dev/null +++ b/crates/eql-types/bindings/v3/Float8Ord.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { OreBlock256 } from "./OreBlock256"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float8_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`). + */ +export type Float8Ord = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * Block-ORE order term (8 blocks for float). Serves equality too. + */ +ob: OreBlock256, }; diff --git a/crates/eql-types/bindings/v3/Float8OrdOre.ts b/crates/eql-types/bindings/v3/Float8OrdOre.ts new file mode 100644 index 00000000..9fd0d718 --- /dev/null +++ b/crates/eql-types/bindings/v3/Float8OrdOre.ts @@ -0,0 +1,27 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { Ciphertext } from "./Ciphertext"; +import type { Identifier } from "./Identifier"; +import type { OreBlock256 } from "./OreBlock256"; +import type { SchemaVersion } from "./SchemaVersion"; + +/** + * `eql_v3.float8_ord_ore` — full comparison, scheme-explicit name. + */ +export type Float8OrdOre = { +/** + * Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + * value fails deserialization. + */ +v: SchemaVersion, +/** + * Table/column identifier. Required by the domain CHECK. + */ +i: Identifier, +/** + * mp_base85 source ciphertext. Required by the domain CHECK. + */ +c: Ciphertext, +/** + * Block-ORE order term (8 blocks for float). Serves equality too. + */ +ob: OreBlock256, }; diff --git a/crates/eql-types/schema/v3/float4.json b/crates/eql-types/schema/v3/float4.json new file mode 100644 index 00000000..747728d8 --- /dev/null +++ b/crates/eql-types/schema/v3/float4.json @@ -0,0 +1,69 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float4.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float4` — storage only; every operator is blocked.", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "v" + ], + "title": "Float4", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float4_eq.json b/crates/eql-types/schema/v3/float4_eq.json new file mode 100644 index 00000000..e8133278 --- /dev/null +++ b/crates/eql-types/schema/v3/float4_eq.json @@ -0,0 +1,82 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float4_eq.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Hmac256": { + "description": "HMAC-SHA-256 equality term — the `hm` wire key. Backs the `_eq` domains (`=`, `<>`). SQL-side constructor: `eql_v3.hmac_256`.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float4_eq` — HMAC equality (`=`, `<>`).", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "hm": { + "allOf": [ + { + "$ref": "#/definitions/Hmac256" + } + ], + "description": "HMAC-SHA-256 equality term." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "hm", + "i", + "v" + ], + "title": "Float4Eq", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float4_ord.json b/crates/eql-types/schema/v3/float4_ord.json new file mode 100644 index 00000000..76d06d29 --- /dev/null +++ b/crates/eql-types/schema/v3/float4_ord.json @@ -0,0 +1,85 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float4_ord.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "OreBlock256": { + "description": "Block-ORE order term — the `ob` wire key. Backs the `_ord` / `_ord_ore` domains (`=` `<>` `<` `<=` `>` `>=`); ORE is lossless over the scalar's domain, so it serves equality too. The block count is width-agnostic on the wire (8 for the int scalars, 12 for timestamptz, 14 for numeric) — the array just carries more block strings. SQL-side constructor: `eql_v3.ore_block_256`.", + "items": { + "type": "string" + }, + "type": "array" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float4_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`).", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "ob": { + "allOf": [ + { + "$ref": "#/definitions/OreBlock256" + } + ], + "description": "Block-ORE order term (8 blocks for float). Serves equality too." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "ob", + "v" + ], + "title": "Float4Ord", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float4_ord_ore.json b/crates/eql-types/schema/v3/float4_ord_ore.json new file mode 100644 index 00000000..1ecbcb1e --- /dev/null +++ b/crates/eql-types/schema/v3/float4_ord_ore.json @@ -0,0 +1,85 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float4_ord_ore.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "OreBlock256": { + "description": "Block-ORE order term — the `ob` wire key. Backs the `_ord` / `_ord_ore` domains (`=` `<>` `<` `<=` `>` `>=`); ORE is lossless over the scalar's domain, so it serves equality too. The block count is width-agnostic on the wire (8 for the int scalars, 12 for timestamptz, 14 for numeric) — the array just carries more block strings. SQL-side constructor: `eql_v3.ore_block_256`.", + "items": { + "type": "string" + }, + "type": "array" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float4_ord_ore` — full comparison, scheme-explicit name.", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "ob": { + "allOf": [ + { + "$ref": "#/definitions/OreBlock256" + } + ], + "description": "Block-ORE order term (8 blocks for float). Serves equality too." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "ob", + "v" + ], + "title": "Float4OrdOre", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float8.json b/crates/eql-types/schema/v3/float8.json new file mode 100644 index 00000000..671d7996 --- /dev/null +++ b/crates/eql-types/schema/v3/float8.json @@ -0,0 +1,69 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float8.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float8` — storage only; every operator is blocked.", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "v" + ], + "title": "Float8", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float8_eq.json b/crates/eql-types/schema/v3/float8_eq.json new file mode 100644 index 00000000..a83bfa1c --- /dev/null +++ b/crates/eql-types/schema/v3/float8_eq.json @@ -0,0 +1,82 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float8_eq.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Hmac256": { + "description": "HMAC-SHA-256 equality term — the `hm` wire key. Backs the `_eq` domains (`=`, `<>`). SQL-side constructor: `eql_v3.hmac_256`.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float8_eq` — HMAC equality (`=`, `<>`).", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "hm": { + "allOf": [ + { + "$ref": "#/definitions/Hmac256" + } + ], + "description": "HMAC-SHA-256 equality term." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "hm", + "i", + "v" + ], + "title": "Float8Eq", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float8_ord.json b/crates/eql-types/schema/v3/float8_ord.json new file mode 100644 index 00000000..2753c67c --- /dev/null +++ b/crates/eql-types/schema/v3/float8_ord.json @@ -0,0 +1,85 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float8_ord.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "OreBlock256": { + "description": "Block-ORE order term — the `ob` wire key. Backs the `_ord` / `_ord_ore` domains (`=` `<>` `<` `<=` `>` `>=`); ORE is lossless over the scalar's domain, so it serves equality too. The block count is width-agnostic on the wire (8 for the int scalars, 12 for timestamptz, 14 for numeric) — the array just carries more block strings. SQL-side constructor: `eql_v3.ore_block_256`.", + "items": { + "type": "string" + }, + "type": "array" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float8_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`).", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "ob": { + "allOf": [ + { + "$ref": "#/definitions/OreBlock256" + } + ], + "description": "Block-ORE order term (8 blocks for float). Serves equality too." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "ob", + "v" + ], + "title": "Float8Ord", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/schema/v3/float8_ord_ore.json b/crates/eql-types/schema/v3/float8_ord_ore.json new file mode 100644 index 00000000..ea2153a7 --- /dev/null +++ b/crates/eql-types/schema/v3/float8_ord_ore.json @@ -0,0 +1,85 @@ +{ + "$id": "https://schemas.cipherstash.com/eql/v3/float8_ord_ore.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "definitions": { + "Ciphertext": { + "description": "mp_base85 source ciphertext — the `c` envelope key.\n\nRequired by every v3 domain CHECK; present on every payload.", + "type": "string" + }, + "Identifier": { + "additionalProperties": false, + "description": "Table + column identifier — wire shape `{\"t\": \"...\", \"c\": \"...\"}`.\n\nShared by every payload.", + "properties": { + "c": { + "description": "Column name.", + "type": "string" + }, + "t": { + "description": "Table name.", + "type": "string" + } + }, + "required": [ + "c", + "t" + ], + "type": "object" + }, + "OreBlock256": { + "description": "Block-ORE order term — the `ob` wire key. Backs the `_ord` / `_ord_ore` domains (`=` `<>` `<` `<=` `>` `>=`); ORE is lossless over the scalar's domain, so it serves equality too. The block count is width-agnostic on the wire (8 for the int scalars, 12 for timestamptz, 14 for numeric) — the array just carries more block strings. SQL-side constructor: `eql_v3.ore_block_256`.", + "items": { + "type": "string" + }, + "type": "array" + }, + "SchemaVersion": { + "const": 2, + "description": "The envelope version field (`v`) — always exactly `2` on the wire.", + "type": "integer" + } + }, + "description": "`eql_v3.float8_ord_ore` — full comparison, scheme-explicit name.", + "properties": { + "c": { + "allOf": [ + { + "$ref": "#/definitions/Ciphertext" + } + ], + "description": "mp_base85 source ciphertext. Required by the domain CHECK." + }, + "i": { + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ], + "description": "Table/column identifier. Required by the domain CHECK." + }, + "ob": { + "allOf": [ + { + "$ref": "#/definitions/OreBlock256" + } + ], + "description": "Block-ORE order term (8 blocks for float). Serves equality too." + }, + "v": { + "allOf": [ + { + "$ref": "#/definitions/SchemaVersion" + } + ], + "description": "Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other value fails deserialization." + } + }, + "required": [ + "c", + "i", + "ob", + "v" + ], + "title": "Float8OrdOre", + "type": "object" +} \ No newline at end of file diff --git a/crates/eql-types/src/v3/float4.rs b/crates/eql-types/src/v3/float4.rs new file mode 100644 index 00000000..10d841f5 --- /dev/null +++ b/crates/eql-types/src/v3/float4.rs @@ -0,0 +1,137 @@ +//! The `float4` encrypted-domain family — an ordered, non-integer scalar +//! backed by IEEE-754 `real` (`f32`). Same four-domain ordered shape as +//! [`crate::v3::int4`] (ORE compares ciphertext, so floats order like +//! integers); see that module for the capability table. +//! +//! Both float widths encrypt through a single f64 crypto path +//! (`Plaintext::Float`): a `real` is widened to f64 before encryption, so the +//! wire shape here is identical to [`crate::v3::float8`] — an 8-block `ob` term +//! (`f64::ENCODED_LEN == 8`, same as `int8`). `float4` vs `float8` is purely a +//! Postgres-surface distinction (column type, domain name). + +use schemars::{schema::RootSchema, schema_for}; + +use crate::v3::terms::{Ciphertext, Hmac256, OreBlock256}; +use crate::v3::DomainType; +use crate::{Identifier, SchemaVersion}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use ts_rs::TS; + +/// `eql_v3.float4` — storage only; every operator is blocked. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float4 { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, +} + +impl DomainType for Float4 { + fn sql_domain_static() -> &'static str { + "eql_v3.float4" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float4) + } +} + +/// `eql_v3.float4_eq` — HMAC equality (`=`, `<>`). +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float4Eq { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// HMAC-SHA-256 equality term. + pub hm: Hmac256, +} + +impl DomainType for Float4Eq { + fn sql_domain_static() -> &'static str { + "eql_v3.float4_eq" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float4Eq) + } +} + +/// `eql_v3.float4_ord_ore` — full comparison, scheme-explicit name. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float4OrdOre { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// Block-ORE order term (8 blocks for float). Serves equality too. + pub ob: OreBlock256, +} + +impl DomainType for Float4OrdOre { + fn sql_domain_static() -> &'static str { + "eql_v3.float4_ord_ore" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float4OrdOre) + } +} + +/// `eql_v3.float4_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`). +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float4Ord { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// Block-ORE order term (8 blocks for float). Serves equality too. + pub ob: OreBlock256, +} + +impl DomainType for Float4Ord { + fn sql_domain_static() -> &'static str { + "eql_v3.float4_ord" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float4Ord) + } +} diff --git a/crates/eql-types/src/v3/float8.rs b/crates/eql-types/src/v3/float8.rs new file mode 100644 index 00000000..fd8c2432 --- /dev/null +++ b/crates/eql-types/src/v3/float8.rs @@ -0,0 +1,136 @@ +//! The `float8` encrypted-domain family — an ordered, non-integer scalar +//! backed by IEEE-754 `double precision` (`f64`), the native width of the float +//! crypto path. Same four-domain ordered shape as [`crate::v3::int4`]; see that +//! module for the capability table. +//! +//! Both float widths encrypt through a single f64 crypto path +//! (`Plaintext::Float`), so the wire shape is identical to +//! [`crate::v3::float4`] — an 8-block `ob` term (`f64::ENCODED_LEN == 8`, same +//! as `int8`). + +use schemars::{schema::RootSchema, schema_for}; + +use crate::v3::terms::{Ciphertext, Hmac256, OreBlock256}; +use crate::v3::DomainType; +use crate::{Identifier, SchemaVersion}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use ts_rs::TS; + +/// `eql_v3.float8` — storage only; every operator is blocked. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float8 { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, +} + +impl DomainType for Float8 { + fn sql_domain_static() -> &'static str { + "eql_v3.float8" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float8) + } +} + +/// `eql_v3.float8_eq` — HMAC equality (`=`, `<>`). +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float8Eq { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// HMAC-SHA-256 equality term. + pub hm: Hmac256, +} + +impl DomainType for Float8Eq { + fn sql_domain_static() -> &'static str { + "eql_v3.float8_eq" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float8Eq) + } +} + +/// `eql_v3.float8_ord_ore` — full comparison, scheme-explicit name. +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float8OrdOre { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// Block-ORE order term (8 blocks for float). Serves equality too. + pub ob: OreBlock256, +} + +impl DomainType for Float8OrdOre { + fn sql_domain_static() -> &'static str { + "eql_v3.float8_ord_ore" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float8OrdOre) + } +} + +/// `eql_v3.float8_ord` — full comparison (`=` `<>` `<` `<=` `>` `>=`). +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TS, JsonSchema)] +#[ts(export, export_to = "v3/")] +#[serde(deny_unknown_fields)] +pub struct Float8Ord { + /// Envelope version — always `2` (`EQL_SCHEMA_VERSION`); any other + /// value fails deserialization. + pub v: SchemaVersion, + /// Table/column identifier. Required by the domain CHECK. + pub i: Identifier, + /// mp_base85 source ciphertext. Required by the domain CHECK. + pub c: Ciphertext, + /// Block-ORE order term (8 blocks for float). Serves equality too. + pub ob: OreBlock256, +} + +impl DomainType for Float8Ord { + fn sql_domain_static() -> &'static str { + "eql_v3.float8_ord" + } + + fn sql_domain(&self) -> &'static str { + Self::sql_domain_static() + } + + fn schema(&self) -> RootSchema { + schema_for!(Float8Ord) + } +} diff --git a/crates/eql-types/src/v3/mod.rs b/crates/eql-types/src/v3/mod.rs index 79f4cb81..e8a05fe8 100644 --- a/crates/eql-types/src/v3/mod.rs +++ b/crates/eql-types/src/v3/mod.rs @@ -50,6 +50,8 @@ use schemars::{schema::RootSchema, schema_for, JsonSchema}; pub mod bool; pub mod date; +pub mod float4; +pub mod float8; pub mod int2; pub mod int4; pub mod int8; @@ -166,5 +168,13 @@ pub fn all() -> Vec> { Box::new(PhantomData::), Box::new(PhantomData::), Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), + Box::new(PhantomData::), ] } From 05e8944011f96e60bc41482026eab07ac30df06a Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 20:06:29 +1000 Subject: [PATCH 3/6] test(v3): wire float4/float8 into the scalar matrix + oracles Fixture routing in the matrix proc-macro plus the float4/float8 arms of the fixture/e2e oracle suites, the sign-boundary monotonicity sweep, the float_special NaN/+/-0/+/-Inf regression suite, and the storage-only matrix snapshot. --- crates/eql-tests-macros/src/lib.rs | 44 ++- .../snapshots/matrix_tests_storage_only.txt | 1 + tests/sqlx/src/fixtures/eql_plaintext.rs | 74 +++++ tests/sqlx/src/fixtures/scalar_fixture.rs | 32 +- tests/sqlx/src/lib.rs | 9 + tests/sqlx/src/scalar_domains.rs | 298 +++++++++++++++++- tests/sqlx/src/scalar_types.rs | 2 + tests/sqlx/tests/encrypted_domain.rs | 9 + .../tests/encrypted_domain/float_special.rs | 132 ++++++++ .../encrypted_domain/property/e2e_oracle.rs | 78 +++++ .../property/fixture_oracle.rs | 10 + tests/sqlx/tests/encrypted_domain/signed.rs | 16 +- 12 files changed, 698 insertions(+), 7 deletions(-) create mode 100644 tests/sqlx/tests/encrypted_domain/float_special.rs diff --git a/crates/eql-tests-macros/src/lib.rs b/crates/eql-tests-macros/src/lib.rs index 7b920b54..f0a5edc9 100644 --- a/crates/eql-tests-macros/src/lib.rs +++ b/crates/eql-tests-macros/src/lib.rs @@ -101,6 +101,17 @@ fn is_numeric_token(token: &str) -> bool { matches!(spec_for_token(token).kind, eql_scalars::ScalarKind::Numeric) } +/// True when `token`'s catalog row is an IEEE-754 float kind (`F32`/`F64`). +/// Like `numeric` it is ordered but non-integer and non-chrono, so it stamps the +/// `float` fixture discriminator and draws its values from the harness accessor +/// (`float4_values()` / `float8_values()`). +fn is_float_token(token: &str) -> bool { + matches!( + spec_for_token(token).kind, + eql_scalars::ScalarKind::F32 | eql_scalars::ScalarKind::F64 + ) +} + /// True when `token`'s catalog row declares no ordered domain — equality-only. /// Replaces the `[eq_only]` marker. Consumed by [`matrix_suite_for_entry`] to /// keep an eq-only type out of the ordered matrix (which exercises ordering @@ -247,6 +258,8 @@ fn scalar_fixture_modules_tokens(list: &ScalarList) -> TokenStream2 { format_ident!("text") } else if is_numeric_token(&token_str) { format_ident!("numeric") + } else if is_float_token(&token_str) { + format_ident!("float") } else if is_storage_only_token(&token_str) { // Storage-only (encryption-only) scalars (`bool`): the fixture // carries no index term (no `hm`/`ob`/`bf`), just the encrypted @@ -255,7 +268,7 @@ fn scalar_fixture_modules_tokens(list: &ScalarList) -> TokenStream2 { } else { panic!( "scalar token `{token_str}` is neither integer, temporal, text, \ - numeric, nor storage-only — no fixture discriminator is wired for its kind" + numeric, float, nor storage-only — no fixture discriminator is wired for its kind" ) }; quote! { @@ -552,6 +565,35 @@ mod tests { assert!(dispatch.contains(r#""text" =>"#)); } + #[test] + fn float_entry_skips_impl_and_stamps_float_fixture() { + // `float4`/`float8` are ordered, non-integer, non-chrono: the impl emitter + // skips them (hand-written in scalar_domains.rs), and the fixture module + // stamps the `float` discriminator drawing from `float4_values()`. + let list = syn::parse_str::("int4 => i32, float4 => F4").unwrap(); + let impls = norm(&scalar_type_impls_tokens(&list)); + assert!(impls.contains("impl ScalarType for i32")); + assert!( + !impls.contains("impl ScalarType for F4"), + "float must skip the generated impl (hand-written instead)" + ); + let mods = norm(&scalar_fixture_modules_tokens(&list)); + assert!(mods.contains("pub mod eql_v2_float4")); + assert!(mods.contains("float ,"), "got: {mods}"); + assert!(mods.contains("float4_values"), "got: {mods}"); + let suites = norm(&scalar_matrix_suites_tokens(&list)); + assert!(suites.contains("pub mod float4")); + assert!(suites.contains("caps = [eq , ord]")); + } + + #[test] + fn float_classification_is_read_from_catalog() { + assert!(is_float_token("float4")); + assert!(is_float_token("float8")); + assert!(!is_float_token("int4")); + assert!(!is_float_token("numeric")); + } + #[test] fn ordered_entry_emits_scalar_matrix_with_eq_ord_caps() { let token: Ident = syn::parse_str("int4").unwrap(); diff --git a/tests/sqlx/snapshots/matrix_tests_storage_only.txt b/tests/sqlx/snapshots/matrix_tests_storage_only.txt index f95f6cff..2ee0819a 100644 --- a/tests/sqlx/snapshots/matrix_tests_storage_only.txt +++ b/tests/sqlx/snapshots/matrix_tests_storage_only.txt @@ -3,6 +3,7 @@ scalars::::matrix__storage_aggregate_typecheck_max scalars::::matrix__storage_aggregate_typecheck_min scalars::::matrix__storage_contained_by_blocker scalars::::matrix__storage_contains_blocker +scalars::::matrix__storage_count_distinct_extractor scalars::::matrix__storage_count_path_cast scalars::::matrix__storage_count_typed_column scalars::::matrix__storage_eq_blocker diff --git a/tests/sqlx/src/fixtures/eql_plaintext.rs b/tests/sqlx/src/fixtures/eql_plaintext.rs index 15d7bfc6..d5d0b517 100644 --- a/tests/sqlx/src/fixtures/eql_plaintext.rs +++ b/tests/sqlx/src/fixtures/eql_plaintext.rs @@ -62,6 +62,8 @@ impl PlaintextSqlType { pub const JSONB: PlaintextSqlType = PlaintextSqlType("jsonb"); pub const NUMERIC: PlaintextSqlType = PlaintextSqlType("numeric"); pub const BOOLEAN: PlaintextSqlType = PlaintextSqlType("boolean"); + pub const REAL: PlaintextSqlType = PlaintextSqlType("real"); + pub const DOUBLE_PRECISION: PlaintextSqlType = PlaintextSqlType("double precision"); pub fn as_str(&self) -> &'static str { self.0 @@ -90,6 +92,8 @@ const fn cast_for_kind(kind: ScalarKind) -> Cast { ScalarKind::Text => Cast::TEXT, ScalarKind::Numeric => Cast::DECIMAL, ScalarKind::Bool => Cast::BOOLEAN, + ScalarKind::F32 => Cast::REAL, + ScalarKind::F64 => Cast::DOUBLE, ScalarKind::Jsonb => { panic!("EqlPlaintext is only implemented for the wired scalar kinds") } @@ -109,6 +113,8 @@ const fn plaintext_sql_type_for_kind(kind: ScalarKind) -> PlaintextSqlType { ScalarKind::Text => PlaintextSqlType::TEXT, ScalarKind::Numeric => PlaintextSqlType::NUMERIC, ScalarKind::Bool => PlaintextSqlType::BOOLEAN, + ScalarKind::F32 => PlaintextSqlType::REAL, + ScalarKind::F64 => PlaintextSqlType::DOUBLE_PRECISION, ScalarKind::Jsonb => { panic!("EqlPlaintext is only implemented for the wired scalar kinds") } @@ -126,6 +132,8 @@ mod sealed { impl Sealed for serde_json::Value {} impl Sealed for rust_decimal::Decimal {} impl Sealed for bool {} + impl Sealed for crate::scalar_domains::F4 {} + impl Sealed for crate::scalar_domains::F8 {} } /// A Rust type usable as a fixture `plaintext` value, carrying its EQL cast @@ -237,6 +245,24 @@ impl EqlPlaintext for bool { } } +impl EqlPlaintext for crate::scalar_domains::F4 { + const KIND: ScalarKind = ScalarKind::F32; + + /// A `real` (f32) is widened to f64 before encryption — there is no f32 + /// crypto path. The widening is exact and monotonic, so the oracle holds. + fn to_plaintext(&self) -> Plaintext { + Plaintext::Float(Some(self.0 as f64)) + } +} + +impl EqlPlaintext for crate::scalar_domains::F8 { + const KIND: ScalarKind = ScalarKind::F64; + + fn to_plaintext(&self) -> Plaintext { + Plaintext::Float(Some(self.0)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -431,4 +457,52 @@ mod tests { other => panic!("expected Plaintext::Boolean(Some(false)), got {other:?}"), } } + + #[test] + fn f4_casts_to_real() { + use crate::scalar_domains::F4; + assert_eq!(::CAST, Cast::REAL); + } + + #[test] + fn f4_plaintext_sql_type_is_real() { + use crate::scalar_domains::F4; + assert_eq!( + ::PLAINTEXT_SQL_TYPE, + PlaintextSqlType::REAL + ); + } + + #[test] + fn f4_to_plaintext_widens_to_float_f64() { + use crate::scalar_domains::F4; + match F4(0.5).to_plaintext() { + Plaintext::Float(Some(v)) => assert_eq!(v, 0.5_f64), + other => panic!("expected Plaintext::Float(Some(0.5)), got {other:?}"), + } + } + + #[test] + fn f8_casts_to_double() { + use crate::scalar_domains::F8; + assert_eq!(::CAST, Cast::DOUBLE); + } + + #[test] + fn f8_plaintext_sql_type_is_double_precision() { + use crate::scalar_domains::F8; + assert_eq!( + ::PLAINTEXT_SQL_TYPE, + PlaintextSqlType::DOUBLE_PRECISION + ); + } + + #[test] + fn f8_to_plaintext_wraps_in_float_variant() { + use crate::scalar_domains::F8; + match F8(1.5).to_plaintext() { + Plaintext::Float(Some(v)) => assert_eq!(v, 1.5_f64), + other => panic!("expected Plaintext::Float(Some(1.5)), got {other:?}"), + } + } } diff --git a/tests/sqlx/src/fixtures/scalar_fixture.rs b/tests/sqlx/src/fixtures/scalar_fixture.rs index 43f8594b..788b54fa 100644 --- a/tests/sqlx/src/fixtures/scalar_fixture.rs +++ b/tests/sqlx/src/fixtures/scalar_fixture.rs @@ -13,7 +13,7 @@ /// Stamp out the `spec()` builder, the `fixture-gen` generator test, and the /// property-test module for a scalar fixture. /// -/// The leading **kind** discriminator (`int` / `temporal` / `text` / `numeric` +/// The leading **kind** discriminator (`int` / `temporal` / `text` / `numeric` / `float` /// / `storage`) selects which property asserts are stamped and which index set /// the fixture declares — the rest of the expansion is identical: /// @@ -174,6 +174,36 @@ macro_rules! scalar_fixture { } }; + // Float scalars (`F4`/`F8`): ordered, non-chrono. Same shape as `numeric` — + // `[Unique, Ore]` indexes, pivot-presence asserts via `OrderedScalar` — + // materialised from the harness float newtypes (no `Match`, no chrono). + (float, $name:literal, $ty:ty, $values:expr $(,)?) => { + $crate::scalar_fixture!(@common $name, $ty, $values, [Unique, Ore]); + + #[cfg(test)] + mod tests { + use super::*; + use $crate::scalar_domains::OrderedScalar; + + #[test] + fn spec_is_complete() { + assert!(spec().check_complete().is_ok()); + } + + #[test] + fn spec_includes_pivots() { + let spec = spec(); + let values = spec.values(); + let min = <$ty as OrderedScalar>::min_pivot(); + let mid = <$ty as OrderedScalar>::mid_pivot(); + let max = <$ty as OrderedScalar>::max_pivot(); + assert!(values.contains(&min), "spec must include min_pivot {min:?}"); + assert!(values.contains(&mid), "spec must include mid_pivot {mid:?}"); + assert!(values.contains(&max), "spec must include max_pivot {max:?}"); + } + } + }; + // Storage-only (encryption-only) scalars (`bool`): the value is encrypted // with NO search index, so the payload is `{v,i,c}` with no term key. The // fixture declares zero indexes (`.storage_only()`), and the property test diff --git a/tests/sqlx/src/lib.rs b/tests/sqlx/src/lib.rs index 9882bbe9..4d3acb38 100644 --- a/tests/sqlx/src/lib.rs +++ b/tests/sqlx/src/lib.rs @@ -2,6 +2,15 @@ //! //! Provides assertion builders and test helpers for EQL functionality tests. +// Self-alias so this crate can be named `eql_tests::…` in paths that must resolve +// identically whether they expand inside the lib (e.g. `scalar_types!(fixture_modules)`) +// or inside an integration-test binary (e.g. `scalar_types!(matrix_suites)` in +// `tests/encrypted_domain/scalars/mod.rs`). Local harness types like +// `scalar_domains::F4`/`F8` are referenced from the `scalar_types.rs` dispatch list +// via the absolute `eql_tests::scalar_domains::F4` path — `crate::…` would resolve to +// the test binary's own crate root in the matrix-suite expansion, not to this lib. +extern crate self as eql_tests; + use sqlx::PgPool; pub mod assertions; diff --git a/tests/sqlx/src/scalar_domains.rs b/tests/sqlx/src/scalar_domains.rs index 318e2e89..8cf43ab2 100644 --- a/tests/sqlx/src/scalar_domains.rs +++ b/tests/sqlx/src/scalar_domains.rs @@ -780,6 +780,292 @@ mod text_value_tests { } } +// `float4`/`float8` are hand-written (like `text`/`numeric`): the proc-macro +// emits `impl ScalarType` only for the integer kinds, and `f32`/`f64` are not +// `Ord` (which `ScalarType` requires), so the newtypes `F4`/`F8` carry `Ord` via +// `total_cmp`. Both widths encrypt through the SINGLE f64 crypto path +// (`Plaintext::Float`), so `float4` vs `float8` is purely a Postgres-surface +// distinction. The newtype + trait impls are necessarily per-width (different +// inner primitive, `PG_TYPE`, pivots, and `as f64` widening), so they are +// hand-written, but the value materialiser is the kind-agnostic part and reuses +// the shared `lazy_values!` macro (as `text`/`numeric` do). + +/// Harness newtype over `f32` for the `float4` scalar. `f32` is not `Ord`, which +/// `ScalarType` requires, so `Ord` is derived from `total_cmp` — safe because NaN +/// is never a fixture (guarded in `float_value_guards`). `#[sqlx(transparent)]` +/// delegates `Type`/`Decode` to the inner `f32` against Postgres `real`. +/// `Default` is `F4(0.0)` (the numeric origin / mid pivot). +/// +/// `#[derive(sqlx::Type)]` + `#[sqlx(transparent)]` already generates the +/// delegating `Type` AND `Decode` (and `Encode`) impls for the newtype, so we do +/// NOT also `#[derive(sqlx::Decode)]` — that would be a conflicting impl. +#[derive(Debug, Clone, Copy, PartialEq, sqlx::Type)] +#[sqlx(transparent)] +pub struct F4(pub f32); + +impl Eq for F4 {} +impl Ord for F4 { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.total_cmp(&other.0) + } +} +impl PartialOrd for F4 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Default for F4 { + fn default() -> Self { + F4(0.0) + } +} +impl std::fmt::Display for F4 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +/// Harness newtype over `f64` for the `float8` scalar. Same design as `F4`: +/// `Ord` via `total_cmp`, `#[sqlx(transparent)]` against Postgres +/// `double precision`, `Default = F8(0.0)`. Like `F4`, the transparent +/// `sqlx::Type` derive also supplies `Decode`/`Encode`, so they are not derived +/// separately. +#[derive(Debug, Clone, Copy, PartialEq, sqlx::Type)] +#[sqlx(transparent)] +pub struct F8(pub f64); + +impl Eq for F8 {} +impl Ord for F8 { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.total_cmp(&other.0) + } +} +impl PartialOrd for F8 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Default for F8 { + fn default() -> Self { + F8(0.0) + } +} +impl std::fmt::Display for F8 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +// `float4`/`float8` value wiring goes through the shared `lazy_values!` +// materialiser (the same macro `text`/`numeric` use), parsing the catalog's +// `Fixture::Float` strings into the newtype. Rust's `str::parse::` accepts +// `"inf"`/`"-inf"`/`"nan"`, so the ±Inf pivots parse natively (NaN is excluded by +// the catalog guards). `float4_values()`/`float8_values()` are public so the +// `eql_v2_float4`/`eql_v2_float8` fixture modules (emitted by +// `scalar_types!(fixture_modules)`) can hand the slice to `scalar_fixture!`. +lazy_values! { + cell = FLOAT4_VALUES_CELL, + accessor = float4_values, + rust_type = F4, + spec = eql_scalars::FLOAT4, + variant = Float, + pg_type = "float4", + parse = |f| match f { + eql_scalars::Fixture::Float(s) => F4(s + .parse() + .unwrap_or_else(|e| panic!("invalid float4 catalog fixture {s:?}: {e}"))), + other => panic!("non-float fixture in float4 catalog row: {other:?}"), + }, +} + +lazy_values! { + cell = FLOAT8_VALUES_CELL, + accessor = float8_values, + rust_type = F8, + spec = eql_scalars::FLOAT8, + variant = Float, + pg_type = "float8", + parse = |f| match f { + eql_scalars::Fixture::Float(s) => F8(s + .parse() + .unwrap_or_else(|e| panic!("invalid float8 catalog fixture {s:?}: {e}"))), + other => panic!("non-float fixture in float8 catalog row: {other:?}"), + }, +} + +/// Render an f64 as a Postgres float SQL literal. Finite values use the numeric +/// Display form; non-finite values use the quoted `'Infinity'` / `'-Infinity'` +/// special-input form (`'inf'` from Rust's Display is NOT a valid SQL float). +fn float_sql_literal(x: f64) -> String { + if x.is_infinite() { + if x.is_sign_positive() { + "'Infinity'".to_string() + } else { + "'-Infinity'".to_string() + } + } else { + format!("{x}") + } +} + +impl ScalarType for F4 { + const PG_TYPE: &'static str = "float4"; + + fn fixture_values() -> &'static [Self] { + float4_values() + } + + fn to_sql_literal(value: &Self) -> String { + float_sql_literal(value.0 as f64) + } + + fn arbitrary_value() -> proptest::strategy::BoxedStrategy { + use proptest::strategy::Strategy; + // Sample the cast-valid fixture set (no NaN/-0.0/non-finite novelty + // beyond the fixtures). Every value already round-trips through `real`. + proptest::sample::select(float4_values().to_vec()).boxed() + } +} + +impl OrderedScalar for F4 { + // Boundary pivots derive from `fixture_values()` (= ±Inf); `mid_pivot` + // inherits `Self::default()` = `F4(0.0)`, a real fixture and the origin. +} + +impl SignedScalar for F4 { + /// Floats are signed about `0.0`; fixtures straddle it. + fn origin() -> Self { + F4(0.0) + } +} + +impl ScalarType for F8 { + const PG_TYPE: &'static str = "float8"; + + fn fixture_values() -> &'static [Self] { + float8_values() + } + + fn to_sql_literal(value: &Self) -> String { + float_sql_literal(value.0) + } + + fn arbitrary_value() -> proptest::strategy::BoxedStrategy { + use proptest::strategy::Strategy; + proptest::sample::select(float8_values().to_vec()).boxed() + } +} + +impl OrderedScalar for F8 {} + +impl SignedScalar for F8 { + fn origin() -> Self { + F8(0.0) + } +} + +/// Guards for the float value wiring: the runtime properties the fixture table +/// relies on (catalog parity, no NaN/`-0.0`, pivots present), plus the f32→f64 +/// widening contract the single-crypto-path design rests on. +#[cfg(test)] +mod float_value_guards { + use super::*; + + #[test] + fn float4_values_match_catalog_and_are_finite_non_negative_zero() { + let vals = float4_values(); + // Parsed from the catalog, in order. + let want: Vec = eql_scalars::FLOAT4 + .fixtures + .iter() + .map(|f| match f { + eql_scalars::Fixture::Float(s) => F4(s.parse().unwrap()), + other => panic!("non-float fixture: {other:?}"), + }) + .collect(); + assert_eq!(vals, want.as_slice()); + // No NaN, no -0.0 (the encoder canonicalizes -0.0 -> +0.0; a duplicate + // would break fetch_fixture_payload's fetch_one). + for v in vals { + assert!(!v.0.is_nan(), "{v:?} is NaN"); + assert!(!(v.0 == 0.0 && v.0.is_sign_negative()), "{v:?} is -0.0"); + } + } + + #[test] + fn float8_values_match_catalog_and_are_finite_non_negative_zero() { + let vals = float8_values(); + let want: Vec = eql_scalars::FLOAT8 + .fixtures + .iter() + .map(|f| match f { + eql_scalars::Fixture::Float(s) => F8(s.parse().unwrap()), + other => panic!("non-float fixture: {other:?}"), + }) + .collect(); + assert_eq!(vals, want.as_slice()); + for v in vals { + assert!(!v.0.is_nan(), "{v:?} is NaN"); + assert!(!(v.0 == 0.0 && v.0.is_sign_negative()), "{v:?} is -0.0"); + } + } + + #[test] + fn float_pivots_and_origin_are_fixtures() { + // min/max/origin must be present verbatim (fetch_fixture_payload fetches + // each pivot's ciphertext at test time). + assert!(float4_values().contains(&::min_pivot())); + assert!(float4_values().contains(&::max_pivot())); + assert!(float4_values().contains(&::origin())); + assert_eq!(::origin(), F4(0.0)); + assert!(float8_values().contains(&::min_pivot())); + assert!(float8_values().contains(&::max_pivot())); + assert!(float8_values().contains(&::origin())); + assert_eq!(::origin(), F8(0.0)); + } + + #[test] + fn float_min_max_pivots_are_the_infinities() { + assert_eq!(::min_pivot(), F4(f32::NEG_INFINITY)); + assert_eq!(::max_pivot(), F4(f32::INFINITY)); + assert_eq!(::min_pivot(), F8(f64::NEG_INFINITY)); + assert_eq!(::max_pivot(), F8(f64::INFINITY)); + } + + /// The whole single-crypto-path design rests on "f32→f64 widening is exact + /// and monotonic". Every catalog fixture is exact-in-f32 (powers of two / + /// halves) and `arbitrary_value()` only samples those, so the property is + /// otherwise untested for f32 values that have NO exact f64-of-an-f32 quirk. + /// Exercise a deliberately NON-representable-in-decimal f32 (`0.1f32`, whose + /// nearest f32 differs from `0.1f64`) and confirm the f32 ordering survives + /// the widening to f64 — i.e. `a < b` as f32 iff `(a as f64) < (b as f64)` + /// for the EXACT bits the crypto path encrypts (`to_plaintext` does + /// `self.0 as f64`). This is a pure-Rust guard; it does not touch the DB. + #[test] + fn f32_to_f64_widening_is_order_preserving_for_non_representable_values() { + // Spread of f32 values that are not "nice" in decimal, straddling 0. + let xs: [f32; 7] = [-0.3, -0.1, -0.0625, 0.0, 0.1, 0.2, 0.3]; + for w in xs.windows(2) { + let (a, b) = (w[0], w[1]); + // f32 strict order matches the widened f64 strict order, bit-for-bit + // on the value the f64 crypto path actually sees. + assert_eq!( + a < b, + (a as f64) < (b as f64), + "widening {a} -> {} reordered relative to {b} -> {}", + a as f64, + b as f64 + ); + // total_cmp (the newtype's Ord source) agrees with the widened cmp. + assert_eq!( + a.total_cmp(&b), + (a as f64).total_cmp(&(b as f64)), + "F4 Ord (total_cmp) disagrees with widened F8 Ord for {a} vs {b}" + ); + } + } +} + /// Per-domain capability + payload shape, resolved from `CATALOG`. Each /// variant maps to a domain suffix (`Eq` => `_eq`, `Search` => `_search`, /// …); its terms, required payload keys, supported operators, and @@ -1344,6 +1630,8 @@ mod pivot_derivation_tests { boundary_pivots_are_fixture_extremes::>(); boundary_pivots_are_fixture_extremes::(); boundary_pivots_are_fixture_extremes::(); + boundary_pivots_are_fixture_extremes::(); + boundary_pivots_are_fixture_extremes::(); } } @@ -1372,6 +1660,8 @@ mod arbitrary_value_tests { draws_a_value::>(); draws_a_value::(); draws_a_value::(); + draws_a_value::(); + draws_a_value::(); } } @@ -1403,7 +1693,9 @@ mod oracle_inventory_tests { "date", "timestamptz", "numeric", - "text" + "text", + "float4", + "float8" ], ); // bool is storage-only: no ordered domain, so it is excluded. @@ -1437,7 +1729,9 @@ mod oracle_inventory_tests { "date", "timestamptz", "numeric", - "text" + "text", + "float4", + "float8" ], "a new ordered scalar must be wired into BOTH oracle suites \ (fixture_oracle.rs and e2e_oracle.rs)" diff --git a/tests/sqlx/src/scalar_types.rs b/tests/sqlx/src/scalar_types.rs index 6b9f6b42..9a9d5abf 100644 --- a/tests/sqlx/src/scalar_types.rs +++ b/tests/sqlx/src/scalar_types.rs @@ -59,6 +59,8 @@ macro_rules! scalar_types { numeric => rust_decimal::Decimal, text => String, bool => bool, + float4 => eql_tests::scalar_domains::F4, + float8 => eql_tests::scalar_domains::F8, } }; } diff --git a/tests/sqlx/tests/encrypted_domain.rs b/tests/sqlx/tests/encrypted_domain.rs index 19ae7dde..58589585 100644 --- a/tests/sqlx/tests/encrypted_domain.rs +++ b/tests/sqlx/tests/encrypted_domain.rs @@ -27,6 +27,15 @@ mod text_match; #[path = "encrypted_domain/signed.rs"] mod signed; +// Float edge-case behavioural suite (NaN / ±0 / ±Inf). Creds/e2e-gated: it +// encrypts the special values FRESH at test time, so NaN never enters the shared +// float8 fixture table (where it would corrupt the all-pairs oracle). Deliberately +// NOT under `scalars::` so the matrix-inventory snapshot does not mis-read it as a +// scalar type (same rationale as `signed` / `text_match`). +#[cfg(feature = "proptest-e2e")] +#[path = "encrypted_domain/float_special.rs"] +mod float_special; + // SteVec jsonb-entry behaviour matrix (the reduced `jsonb_entry_matrix!`). // Deliberately NOT under `scalars::` — `JsonbEntryInt4` is not a catalog scalar, // so its names live under `jsonb_entry::…` and are pinned by the separate diff --git a/tests/sqlx/tests/encrypted_domain/float_special.rs b/tests/sqlx/tests/encrypted_domain/float_special.rs new file mode 100644 index 00000000..263cfe33 --- /dev/null +++ b/tests/sqlx/tests/encrypted_domain/float_special.rs @@ -0,0 +1,132 @@ +//! Float edge-case behavioural regression suite (CIP — float4/float8). +//! +//! Captures the NaN / `-0.0` / `+0.0` / `±Inf` behaviour that the shared +//! all-pairs oracle deliberately excludes from its fixtures (NaN is unordered +//! and unspecified in the encoder; `-0.0` canonicalizes to `+0.0`). It encrypts +//! the special values FRESH through cipherstash at test time, so NaN never +//! enters the `float8` fixture table. +//! +//! IMPORTANT: the NaN eq/order outcomes asserted here are an **artifact of the +//! canonical NaN bit pattern + deterministic index terms (hm/ore are pure +//! functions of plaintext+key)**, NOT a supported guarantee, and they diverge +//! from IEEE (`NaN != NaN`). They are discovered-and-locked on first run. +//! +//! The `-0.0`/`+0.0` equality below pins the `orderable-bytes` ORE path, which +//! canonicalizes `-0.0 -> +0.0` before encoding. A dormant alternative encoder +//! (`cllw-ore`) instead distinguishes them; if float ORE is ever routed through +//! that path this test flips from "equal" to "`-0.0 < +0.0`" — it is the canary, +//! so keep this comment pointing at the orderable-bytes canonicalization. + +use anyhow::Result; +use eql_tests::fixtures::cipherstash::{column_config_for, encrypt_store}; +use eql_tests::fixtures::eql_plaintext::EqlPlaintext; +use eql_tests::fixtures::index_kind::IndexKind; +use eql_tests::property::{connect_pool, ensure_eql_installed}; +use eql_tests::scalar_domains::F8; +use sqlx::PgPool; + +/// Encrypt one batch of f64 special values into payload JSON strings, one +/// ZeroKMS round trip. Mirrors `e2e_oracle::encrypt_rows` but returns only the +/// payloads (these tests key on position, not plaintext). `encrypt_store` +/// encrypts through cipherstash-client directly — it needs no `PgPool`. +async fn encrypt_specials(values: &[F8]) -> Result> { + let config = column_config_for( + &[IndexKind::Unique, IndexKind::Ore], + ::CAST, + )?; + let payloads = encrypt_store("float_special", "payload", values, &config).await?; + Ok(payloads.into_iter().map(|p| p.to_string()).collect()) +} + +/// Cast a payload literal to `eql_v3.float8` and read it back, proving the domain +/// CHECK accepts the encrypted special value. +async fn cast_passes_check(pool: &PgPool, payload: &str) -> Result<()> { + let sql = "SELECT ($1::jsonb::eql_v3.float8) IS NOT NULL"; + let ok: bool = sqlx::query_scalar(sql) + .bind(payload) + .fetch_one(pool) + .await?; + anyhow::ensure!(ok, "payload failed the eql_v3.float8 CHECK: {payload}"); + Ok(()) +} + +/// Compare two payloads under an operator on the `_ord` domain, returning the +/// boolean result. Used to pin the discovered NaN/±0/±Inf outcomes. +async fn ord_cmp(pool: &PgPool, a: &str, op: &str, b: &str) -> Result { + let d = "eql_v3.float8_ord"; + let sql = format!("SELECT ($1::jsonb::{d} {op} $2::jsonb::{d})"); + Ok(sqlx::query_scalar(&sql) + .bind(a) + .bind(b) + .fetch_one(pool) + .await?) +} + +/// Equality under the `_eq` domain (HMAC). +async fn eq_cmp(pool: &PgPool, a: &str, b: &str) -> Result { + let d = "eql_v3.float8_eq"; + let sql = format!("SELECT ($1::jsonb::{d} = $2::jsonb::{d})"); + Ok(sqlx::query_scalar(&sql) + .bind(a) + .bind(b) + .fetch_one(pool) + .await?) +} + +async fn setup() -> Result { + let pool = connect_pool().await?; + ensure_eql_installed(&pool, &crate::property::migrator()).await?; + Ok(pool) +} + +#[tokio::test] +async fn nan_encrypts_and_passes_check() -> Result<()> { + // Encrypting f64::NAN succeeds (no panic) and yields a structurally valid + // eql_v3.float8 payload. This is the one universal NaN guarantee. + let pool = setup().await?; + let payloads = encrypt_specials(&[F8(f64::NAN)]).await?; + assert_eq!(payloads.len(), 1); + cast_passes_check(&pool, &payloads[0]).await?; + Ok(()) +} + +#[tokio::test] +async fn two_encryptions_of_same_nan_bits_compare_equal() -> Result<()> { + // ARTIFACT, NOT A GUARANTEE: index terms are deterministic functions of + // plaintext+key, so two encryptions of the SAME canonical NaN bit pattern + // produce the same hm/ore terms and compare equal under `=` — diverging from + // IEEE (NaN != NaN). Locked on first run; if the encoder's canonical NaN + // handling changes, this fails loudly and the comment must be revisited. + let pool = setup().await?; + let p = encrypt_specials(&[F8(f64::NAN), F8(f64::NAN)]).await?; + let equal = eq_cmp(&pool, &p[0], &p[1]).await?; + assert!( + equal, + "two encryptions of canonical NaN compare equal (artifact of deterministic terms)" + ); + Ok(()) +} + +#[tokio::test] +async fn negative_zero_and_positive_zero_compare_equal_and_share_ore() -> Result<()> { + // The encoder canonicalizes -0.0 -> +0.0 (byte-equal), matching IEEE + // (-0.0 == 0.0). So they compare equal under `=` and are not `<` either way. + let pool = setup().await?; + let p = encrypt_specials(&[F8(-0.0), F8(0.0)]).await?; + assert!(eq_cmp(&pool, &p[0], &p[1]).await?, "-0.0 == +0.0"); + assert!(!ord_cmp(&pool, &p[0], "<", &p[1]).await?, "-0.0 not < +0.0"); + assert!(!ord_cmp(&pool, &p[1], "<", &p[0]).await?, "+0.0 not < -0.0"); + Ok(()) +} + +#[tokio::test] +async fn infinities_order_correctly() -> Result<()> { + // Redundant spot-check of the boundary ordering: -Inf < 0 < +Inf through the + // encrypted _ord domain (no decryption). + let pool = setup().await?; + let p = encrypt_specials(&[F8(f64::NEG_INFINITY), F8(0.0), F8(f64::INFINITY)]).await?; + assert!(ord_cmp(&pool, &p[0], "<", &p[1]).await?, "-Inf < 0"); + assert!(ord_cmp(&pool, &p[1], "<", &p[2]).await?, "0 < +Inf"); + assert!(ord_cmp(&pool, &p[0], "<", &p[2]).await?, "-Inf < +Inf"); + Ok(()) +} diff --git a/tests/sqlx/tests/encrypted_domain/property/e2e_oracle.rs b/tests/sqlx/tests/encrypted_domain/property/e2e_oracle.rs index 905fc4d4..3fce0980 100644 --- a/tests/sqlx/tests/encrypted_domain/property/e2e_oracle.rs +++ b/tests/sqlx/tests/encrypted_domain/property/e2e_oracle.rs @@ -186,3 +186,81 @@ e2e_oracle_suite!( "proptest_e2e_text", seeds = ["aard".to_string(), "frank".to_string(), "zzzz".to_string()] ); +e2e_oracle_suite!( + float4, + eql_tests::scalar_domains::F4, + "proptest_e2e_float4", + seeds = [ + eql_tests::scalar_domains::F4(f32::NEG_INFINITY), + eql_tests::scalar_domains::F4(0.0), + eql_tests::scalar_domains::F4(f32::INFINITY), + ] +); +e2e_oracle_suite!( + float8, + eql_tests::scalar_domains::F8, + "proptest_e2e_float8", + seeds = [ + eql_tests::scalar_domains::F8(f64::NEG_INFINITY), + eql_tests::scalar_domains::F8(0.0), + eql_tests::scalar_domains::F8(f64::INFINITY), + ] +); + +/// Both float widths encrypt through the SINGLE f64 crypto path +/// (`F4::to_plaintext` widens `self.0 as f64`; `F8::to_plaintext` is the +/// identity), so an f32 value and its exact f64 widening MUST produce identical +/// index terms — this is the byte-identity the CHANGELOG claims. Encrypt the +/// same value both ways (an f32-exact value, so `x as f64` is lossless) and +/// assert the `hm` (HMAC equality) and `ob` (ORE) terms match across widths. +/// Creds/e2e-gated like the rest of this file. +#[test] +fn float4_and_float8_share_index_terms_for_the_same_value() -> Result<()> { + use eql_tests::scalar_domains::{F4, F8}; + + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; + + // f32-exact value: `x as f64` is the same real number, so any term + // difference would be a width artifact, which is exactly what we forbid. + let x: f32 = 2.25; + + let f4_payloads = rt.block_on(async { + let cfg = column_config_for( + &[IndexKind::Unique, IndexKind::Ore], + ::CAST, + )?; + encrypt_store("xwidth_f4", "payload", &[F4(x)], &cfg).await + })?; + let f8_payloads = rt.block_on(async { + let cfg = column_config_for( + &[IndexKind::Unique, IndexKind::Ore], + ::CAST, + )?; + encrypt_store("xwidth_f8", "payload", &[F8(x as f64)], &cfg).await + })?; + + // Pull a string index term from the EQL payload JSON (`hm` / `ob`). + let term = |p: &serde_json::Value, key: &str| -> Result { + p.get(key) + .and_then(serde_json::Value::as_str) + .map(str::to_string) + .ok_or_else(|| anyhow::anyhow!("payload missing string `{key}`: {p}")) + }; + + // HMAC equality term: identical plaintext + key => identical hm, so the two + // widths are equality-interchangeable at the term level. + assert_eq!( + term(&f4_payloads[0], "hm")?, + term(&f8_payloads[0], "hm")?, + "float4 and float8 of the same value must share the hm equality term" + ); + // ORE term: same f64 input => same ORE ciphertext, so ordering is identical. + assert_eq!( + term(&f4_payloads[0], "ob")?, + term(&f8_payloads[0], "ob")?, + "float4 and float8 of the same value must share the ob ORE term" + ); + Ok(()) +} diff --git a/tests/sqlx/tests/encrypted_domain/property/fixture_oracle.rs b/tests/sqlx/tests/encrypted_domain/property/fixture_oracle.rs index 5e940ab0..cf5d8645 100644 --- a/tests/sqlx/tests/encrypted_domain/property/fixture_oracle.rs +++ b/tests/sqlx/tests/encrypted_domain/property/fixture_oracle.rs @@ -64,6 +64,14 @@ fn embedded_fixture_sql() -> &'static str { env!("CARGO_MANIFEST_DIR"), "/fixtures/eql_v2_numeric.sql" )), + "float4" => include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/fixtures/eql_v2_float4.sql" + )), + "float8" => include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/fixtures/eql_v2_float8.sql" + )), other => panic!( "no embedded fixture for catalog token '{other}'; \ add an include_str! arm in fixture_oracle.rs" @@ -240,3 +248,5 @@ fixture_oracle_suite!(date, chrono::NaiveDate, ordered); fixture_oracle_suite!(timestamptz, chrono::DateTime, ordered); fixture_oracle_suite!(numeric, rust_decimal::Decimal, ordered); fixture_oracle_suite!(text, String, ordered); +fixture_oracle_suite!(float4, eql_tests::scalar_domains::F4, ordered); +fixture_oracle_suite!(float8, eql_tests::scalar_domains::F8, ordered); diff --git a/tests/sqlx/tests/encrypted_domain/signed.rs b/tests/sqlx/tests/encrypted_domain/signed.rs index 08b8b6bc..19b822ae 100644 --- a/tests/sqlx/tests/encrypted_domain/signed.rs +++ b/tests/sqlx/tests/encrypted_domain/signed.rs @@ -1,9 +1,9 @@ //! Sign-boundary coverage for **signed** scalars (`int2`/`int4`/`int8`, `date`, -//! `timestamptz`) — the `SignedScalar` delta on top of the uniform ordered -//! matrix. +//! `timestamptz`, `float4`/`float8`) — the `SignedScalar` delta on top of the +//! uniform ordered matrix. //! //! ORE encrypts signed values as an offset from a numeric origin (`0` for -//! integers, the epoch for `date`/`timestamptz`). This suite asserts the ORE block ordering is +//! integers and floats, the epoch for `date`/`timestamptz`). This suite asserts the ORE block ordering is //! **monotonic across that origin**: a fixture below the origin orders before //! the origin, which orders before a fixture above it — through the encrypted //! `_ord` domain, with no decryption. @@ -67,3 +67,13 @@ async fn int8_sign_boundary(pool: PgPool) -> anyhow::Result<()> { async fn timestamptz_sign_boundary(pool: PgPool) -> anyhow::Result<()> { sign_boundary_is_monotonic::>(&pool).await } + +#[sqlx::test(fixtures(path = "../../fixtures", scripts("eql_v2_float4")))] +async fn float4_sign_boundary(pool: PgPool) -> anyhow::Result<()> { + sign_boundary_is_monotonic::(&pool).await +} + +#[sqlx::test(fixtures(path = "../../fixtures", scripts("eql_v2_float8")))] +async fn float8_sign_boundary(pool: PgPool) -> anyhow::Result<()> { + sign_boundary_is_monotonic::(&pool).await +} From f299ecd3be3dd5844592d6515d1eb6a8b33314b2 Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 20:06:29 +1000 Subject: [PATCH 4/6] docs(v3): changelog entry for float4/float8 encrypted domains CHANGELOG Added entry for the float4/float8 families, with the IEEE-754 caveats (NaN ordering, +/-0 equality, f64 widening) folded inline. No docs/upgrading/ note: this is additive eql_v3, not an eql_v2 release. --- CHANGELOG.md | 1 + .../2026-06-19-float-encrypted-domain-plan.md | 233 +++++++++++++----- 2 files changed, 175 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb65ef95..56cb547a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Each entry that ships in a published release links to the PR that introduced it. - **Self-contained `eql_v3` schema + standalone `release/cipherstash-encrypt-v3.sql` installer.** The `eql_v3` encrypted-domain surface no longer depends on `eql_v2` at runtime: it now owns its own copies of the searchable-encrypted-metadata (SEM) index-term types — `eql_v3.hmac_256` and `eql_v3.ore_block_u64_8_256` (with its btree operator class) — so the `eql_v3.eq_term` / `eql_v3.ord_term` extractors return `eql_v3` types and no `eql_v2.` appears anywhere in the v3 SQL. The whole v3 surface relocated under a single `src/v3/` tree (`src/v3/sem/` for the hand-written SEM types, `src/v3/scalars/` for the generated domain families). A new build variant ships the `eql_v3` schema on its own as `release/cipherstash-encrypt-v3.sql`, installable into a database with no `eql_v2` present; a CI gate greps that artifact and its dependency closure to keep it `eql_v2`-free. Why: a clean foundation for the per-scalar encrypted-domain model to stand alone, ahead of it replacing the `eql_v2_encrypted` composite column type. This is additive — a new schema and a new artifact — and leaves `eql_v2` byte-for-byte unchanged. ([#255](https://github.com/cipherstash/encrypt-query-language/pull/255)) - **`eql_v3.min` / `eql_v3.max` aggregates over `eql_v3.ste_vec_entry`.** SteVec document entries extracted at a selector (`doc -> 'sel'`) can now be aggregated like ordered scalars: `eql_v3.min(doc -> 'sel')` / `eql_v3.max(...)` return the entry with the smallest / largest ordered leaf. Ordering routes through the entry's `oc` (CLLW ORE) term via `eql_v3.ore_cllw` — the same comparator the entry `<` / `<=` / `>` / `>=` operators use, not the scalar Block-ORE `ord_term`. Only `oc`-carrying entries are orderable: an entry without an `oc` term (`eql_v3.ore_cllw` returns NULL) is non-orderable and is ignored by the aggregate — the same way the `eql_v3.ore_cllw` btree NULL-filters such rows — so a mix of `oc`-carrying and `oc`-less entries yields the extremum of the orderable subset rather than a corrupted result. Declared `PARALLEL = SAFE` with a combine function (the state function itself), so partial / parallel aggregation is available on large `GROUP BY` workloads. Why: brings encrypted-JSONB entry ordering to parity with the scalar encrypted-domain families' `MIN` / `MAX`, and lets the shared scalar behaviour matrix cover entry aggregation. Additive — the document and entry comparison surface is otherwise unchanged. ([#267](https://github.com/cipherstash/encrypt-query-language/pull/267)) - **`eql_v3.bool` encrypted-domain type family (storage-only / encryption-only).** A single jsonb-backed domain for encrypted `bool` columns — `eql_v3.bool` — generated from the `bool` row in `eql-scalars::CATALOG`. Unlike every other scalar family, `bool` is **encryption-only**: it carries no SEM index term and exposes **no** `_eq` / `_ord` domains, so the value is encrypted at rest and decrypted by the proxy but is **not searchable server-side**. This is deliberate — a two-value column has so little cardinality that any searchable index (even HMAC equality) would trivially leak the plaintext distribution. Every comparison / containment / path operator reachable through domain fallback (`=`, `<>`, `<`, `<=`, `>`, `>=`, `@>`, `<@`, `->`, `->>`, …) is blocked (raises rather than silently routing to plaintext-`jsonb` semantics); the domain `CHECK` still requires the EQL envelope (`v`, `i`), the ciphertext (`c`), and pins the payload version (`VALUE->>'v' = '2'`). The encrypted payload is `{v,i,c}` only — no `hm` / `ob` / `bf` term. Why: lets callers encrypt a low-cardinality boolean column at rest without offering a server-side search surface that would leak it; the first **storage-only** member of the generated scalar encrypted-domain family. ([#295](https://github.com/cipherstash/encrypt-query-language/pull/295)) +- **`eql_v3.float4` / `eql_v3.float8` encrypted-domain type families (ordered).** Four jsonb-backed domains each for encrypted `real` / `double precision` columns — `eql_v3.float4` / `eql_v3.float8` (storage-only), `eql_v3._eq` (`=` / `<>` via HMAC), and `eql_v3._ord` / `eql_v3._ord_ore` (also `<` `<=` `>` `>=`, `MIN` / `MAX` via 8-block ORE) — generated from the `float4` / `float8` rows in `eql-scalars::CATALOG` by the same materializer as the `eql_v3.int4` reference. Both widths encrypt through a single f64 crypto path (`Plaintext::Float`): a `real` is widened to f64 before encryption (exact and monotonic), so `float4` vs `float8` is purely a Postgres-surface distinction and the ciphertext / ORE term are byte-identical. Ordering is correct for all non-NaN values via the standard monotonic IEEE-754 byte mapping (`f64::ENCODED_LEN == 8`, same as `int8`); `-0.0` canonicalizes to `+0.0` and `±Inf` order correctly. NaN is unordered and unspecified in the encoder — it can be encrypted and stored but is not given a meaningful comparison guarantee (any NaN rejection is client-side). Index via a functional index on the `eql_v3.eq_term` / `eql_v3.ord_term` extractors, not an operator class on the domain. Why: a type-safe, per-capability encrypted IEEE-754 float column, closing the gap for `real` / `double` columns that had no v3 equivalent (the v3 `numeric` family is arbitrary-precision decimal, not binary float). ([#299](https://github.com/cipherstash/encrypt-query-language/pull/299)) ### Changed diff --git a/docs/plans/2026-06-19-float-encrypted-domain-plan.md b/docs/plans/2026-06-19-float-encrypted-domain-plan.md index 6d85541a..e6acfeb4 100644 --- a/docs/plans/2026-06-19-float-encrypted-domain-plan.md +++ b/docs/plans/2026-06-19-float-encrypted-domain-plan.md @@ -6,6 +6,8 @@ **Architecture:** `float4`/`float8` are **ordered scalars** reusing the existing four-domain shape `ORDERED_INT_DOMAINS` (storage `""`, `_eq` `[Hm]`, `_ord_ore` `[Ore]`, `_ord` `[Ore]`) — the same shape `int4`/`numeric` use. They are duplicated across two Postgres widths but **both encrypt through a single f64 crypto path** (`Plaintext::Float(Some(x as f64))`); `float4` vs `float8` is purely a Postgres-surface distinction (column type, domain name, decrypt type). Float is a brand-new `ScalarKind` (two variants `F32`/`F64`), so — like `numeric` — it touches the proc-macro fixture-router, not just the type list. No new comparator, no new domain shape, no new operators: the kind-agnostic codegen renderers (confirmed below to switch on nothing) generate the SQL, and the N-block ORE comparator already orders f64 (`f64::ENCODED_LEN == 8`, same as `i64`). +**Cross-width comparison is out of scope (by design).** `eql_v3.float4` and `eql_v3.float8` are **separate domains**, exactly as `eql_v3.int4` and `eql_v3.int8` are. The codegen operator renderer emits each operator overload per-domain with operands `(Domain, Domain)`, `(Domain, jsonb)`, or `(jsonb, Domain)` — both operand slots resolve to the *same* domain or raw `jsonb` (verified in `crates/eql-codegen/src/operator_surface.rs` / `generate.rs::render_operators_file`). There is **no cross-type operator** anywhere in the generated surface (no `int4`-vs-`int8`, hence no `float4`-vs-`float8`). So comparing an `eql_v3.float4` payload against an `eql_v3.float8` payload is **not a supported operation** — a caller wanting to compare across widths casts both sides to the same domain at the plaintext layer before encryption. This mirrors the integer families and needs no new test: the all-pairs oracle is per-type, and int-width cross-comparison is not tested either (there is nothing to assert — the operator does not exist). + **Tech Stack:** Rust (`eql-scalars` catalog crate, `eql-codegen` renderer crate, `eql-tests-macros` proc-macros, `eql_tests` SQLx harness), minijinja SQL templates, PostgreSQL 14–17, `cargo`/`mise` task runner, proptest, cipherstash-client. ## Global Constraints @@ -20,6 +22,7 @@ These apply to **every** task. Copied from the design spec and `docs/reference/a - **Both floats are `SignedScalar`**, origin `0.0` (diverging from `numeric`, which opted out), so the signed-zero boundary runs through `encrypted_domain/signed.rs`. - **Verification command order** (per the design's Verification plan §, mirroring the procedure doc §4): `cargo run -p eql-codegen` → `mise run test:codegen` → `mise run test:matrix:inventory` → `mise run clean && mise run build` → the float SQLx suites + `float_special` → `mise run test` → `mise run test:self_contained_v3` → commit the reference baselines. - **Run `mise run clean && mise run build`**, never a bare build — a bare build can leave stale `release/*.sql`. +- **Inter-task compile coupling (Task 1 ↔ Task 3).** `cast_for_kind` and `plaintext_sql_type_for_kind` in `tests/sqlx/src/fixtures/eql_plaintext.rs` are **exhaustive, non-wildcard `match`es over `ScalarKind`** (only `Jsonb` panics; no `_ =>` arm — verified). Adding `ScalarKind::F32`/`F64` in Task 1 therefore makes `eql_tests` (and anything that depends on it) **fail to compile** with non-exhaustive-match errors until Task 3 adds the four arms. This is expected. Verify Task 1 in isolation with `cargo test -p eql-scalars` (the catalog crate is zero-dep and does not see those matches); do not run a whole-workspace `cargo test` between Task 1 and Task 3 and mistake the match errors for a Task 1 mistake. - **Changelog discipline.** This is a user-facing addition: a `[Unreleased]` `Added` entry plus an upgrade note are required (Task 9). Do **not** stage or commit the pre-existing uncommitted changes in the worktree. --- @@ -49,7 +52,7 @@ Files created or modified, grouped by responsibility (maps to the design's group **D. Artefacts & docs** - `tests/codegen/reference/float4/`, `tests/codegen/reference/float8/` — committed reference baselines. -- `CHANGELOG.md` + `docs/upgrading/v2.4.md` upgrade note. +- `CHANGELOG.md` entry (IEEE-754 caveats folded inline; no separate upgrade doc — this is additive `eql_v3`, not an `eql_v2` release). > **Note for the implementer — spec path corrections.** The design's File-by-file list says the oracle suites live at `tests/sqlx/tests/encrypted_domain/{fixture_oracle.rs, e2e_oracle.rs}`. They actually live under `property/` (`tests/sqlx/tests/encrypted_domain/property/fixture_oracle.rs` and `.../property/e2e_oracle.rs`). The `#[path]` mod for `float_special` goes in `tests/sqlx/tests/encrypted_domain.rs` (which registers `text_smoke`/`text_match`/`signed` outside `scalars::`). Use the paths in this plan. @@ -189,9 +192,8 @@ In `crates/eql-scalars/src/lib.rs`, add two variants to `enum ScalarKind` (after /// (`Plaintext::Float`) — the f32→f64 widening is exact and monotonic. F32, /// 64-bit IEEE-754 binary float (`f64`, Postgres `double precision`/ - /// `float8`). The native width of the float crypto path. Ordered like the - /// integer kinds via ORE (`f64::ENCODED_LEN == 8`, same as `i64`); no i128 - /// range. + /// `float8`). The native width of the float crypto path (`F32` widens into + /// it); otherwise classified exactly like [`ScalarKind::F32`]. F64, ``` @@ -224,8 +226,8 @@ In `crates/eql-scalars/src/lib.rs`, after the `BOOL` spec, add the fixture lists /// f32 (powers of two and halves), so the `real` round-trip is lossless and the /// f32→f64 widening before encryption is exact. The three pivots MUST be present /// verbatim: `"-inf"` (min_pivot), `"0"` (origin/mid), `"inf"` (max_pivot). -/// NaN and `-0.0` are deliberately excluded (see the `float_special` suite). All -/// distinct by value. +/// NaN and `-0.0` are deliberately excluded (see the `float_special` suite). +/// Distinctness is enforced by `Fixture::Float` (above) and its guard test. const FLOAT4_FIXTURES: &[Fixture] = fixtures!(float; "-inf", "-1024", "-2.25", "-1", "-0.5", "-0.25", "0", "0.25", "0.5", "1", "2.25", "1024", "inf"); @@ -234,7 +236,7 @@ const FLOAT4_FIXTURES: &[Fixture] = fixtures!(float; /// harness. The native width of the float crypto path; values span sign and /// magnitude including subnormal-free interior points. The three pivots MUST be /// present verbatim: `"-inf"` (min_pivot), `"0"` (origin/mid), `"inf"` -/// (max_pivot). NaN and `-0.0` are deliberately excluded. All distinct by value. +/// (max_pivot). NaN and `-0.0` are deliberately excluded. const FLOAT8_FIXTURES: &[Fixture] = fixtures!(float; "-inf", "-1e300", "-1000000", "-1.5", "-1", "-0.001", "0", "0.001", "1", "1.5", "1000000", "1e300", "inf"); @@ -336,13 +338,23 @@ In `crates/eql-scalars/src/tests.rs`, update `catalog_has_int4_int2_int8_date_ti } ``` -Also check `storage_only_is_exclusive_to_bool`, `every_type_uses_a_known_domain_shape`, and `as_bounded_int_maps_integer_kinds_only` — they iterate `CATALOG` and already handle non-integer/non-storage kinds generically (float is ordered + non-storage + non-integer, identical to `numeric`), so no change is expected. If `as_bounded_int_maps_integer_kinds_only` enumerates kinds explicitly, add `F32`/`F64` to its non-integer list. +Three existing tests in `rust_tests` **enumerate `ScalarKind::` variants explicitly** (not generically over `CATALOG`) and must learn the two new kinds, or their coverage silently lapses — verified against `crates/eql-scalars/src/tests.rs`: + +- `as_bounded_int_maps_integer_kinds_only` (line 36) — a flat list of `assert_eq!(ScalarKind::X.as_bounded_int(), None)` calls; add `assert_eq!(ScalarKind::F32.as_bounded_int(), None);` and the `F64` twin. +- `is_int_classifies_kinds` (line 74) — a flat list of `assert!(!ScalarKind::X.is_int())`; add `assert!(!ScalarKind::F32.is_int());` and the `F64` twin. +- `is_text_classifies_only_text` (line 86) — a `for k in [ … ]` array of non-text kinds; add `ScalarKind::F32, ScalarKind::F64` to that array. + +(Optionally also add the two kinds to `is_temporal_classifies_chrono_kinds` (line 168), whose non-temporal list currently stops at the integer kinds.) The new `float_tests::float_kinds_are_not_bounded_int_temporal_or_text` (Step 1) already asserts these properties for `F32`/`F64` directly, but the existing per-classifier tests should still enumerate them so a future regression in one classifier fails its own test, not only the float bundle. + +The genuinely generic catalog tests — `storage_only_is_exclusive_to_bool`, `every_type_uses_a_known_domain_shape`, `every_int_kind_matches_its_rust_type` (iterates `CATALOG.filter(is_int)`, so float is skipped) — iterate `CATALOG` and need no change (float is ordered + non-storage + non-integer, identical to `numeric`). - [ ] **Step 9: Run the eql-scalars tests to verify they pass** Run: `cargo test -p eql-scalars` Expected: PASS — including the new `float_tests` and the updated catalog-order test. If `mod proptest_invariants` or any other catalog test enumerates kinds/tokens, fix it here. +> **Scope this to `-p eql-scalars`.** Do NOT run a workspace-wide `cargo test` here: adding `F32`/`F64` to `ScalarKind` breaks the exhaustive `match`es in `eql_plaintext.rs` (see Global Constraints — "Inter-task compile coupling"), so `eql_tests` will not compile until Task 3. That is expected, not a Task 1 regression. The catalog crate is zero-dep and compiles/tests cleanly on its own. + - [ ] **Step 10: Generate the float SQL and confirm the renderers are kind-agnostic (THE RISK CHECK)** Run: `cargo run -p eql-codegen` @@ -373,6 +385,8 @@ git commit -m "feat(v3): add float4/float8 catalog rows + Float kind/fixture" Float owns `f32`/`f64`, which are not `Ord` and not directly `ScalarType`-able, so — like `numeric` (`Decimal`) and `text` (`String`) — the `impl ScalarType` is hand-written in `scalar_domains.rs`. The newtypes `F4`/`F8` carry `Ord` via `total_cmp`, `Display`, `Default = 0.0`, and `#[sqlx(transparent)]` for `Type`/`Decode` against `real`/`double precision`. +> **On the F4/F8 duplication (hand-written is the house style here).** The newtype trait impls (`Eq`/`Ord`/`PartialOrd`/`Default`/`Display`) plus `ScalarType`/`OrderedScalar`/`SignedScalar` are ~near-identical per width, and the temptation is a `float_values!`-style twin macro (cf. the existing `temporal_values!` / `lazy_values!` macros in `scalar_domains.rs`). Resist it: those two macros exist to share a *kind-agnostic* core across genuinely different kinds (`date`/`timestamptz` are both chrono; `text`/`numeric` both owned-string-parsed). `text`, `numeric`, and `bool` each **hand-write their own `impl ScalarType`** per kind precisely because each kind's `to_sql_literal` / pivots / signedness differ — that is the established pattern for distinct kinds. `F4`/`F8` differ in inner primitive (`f32` vs `f64`), `PG_TYPE`, `min/max_pivot` (`f32::INFINITY` vs `f64::INFINITY`), and the `as f64` widening, so a macro would be parameterised on nearly everything anyway. **Do reuse the existing `lazy_values!` macro for the value accessors** (as `numeric` does — see Step 4), since that part *is* kind-agnostic; keep the newtype + trait impls hand-written. One macro reuse for the materialiser, no new macro for the impls. + **Files:** - Modify: `tests/sqlx/src/scalar_domains.rs` (newtypes, accessors, impls, guards, test-list additions) @@ -449,9 +463,44 @@ mod float_value_guards { assert_eq!(::min_pivot(), F8(f64::NEG_INFINITY)); assert_eq!(::max_pivot(), F8(f64::INFINITY)); } + + /// The whole single-crypto-path design rests on "f32→f64 widening is exact + /// and monotonic". Every catalog fixture is exact-in-f32 (powers of two / + /// halves) and `arbitrary_value()` only samples those, so the property is + /// otherwise untested for f32 values that have NO exact f64-of-an-f32 quirk. + /// Exercise a deliberately NON-representable-in-decimal f32 (`0.1f32`, whose + /// nearest f32 differs from `0.1f64`) and confirm the f32 ordering survives + /// the widening to f64 — i.e. `a < b` as f32 iff `(a as f64) < (b as f64)` + /// for the EXACT bits the crypto path encrypts (`to_plaintext` does + /// `self.0 as f64`). This is a pure-Rust guard; it does not touch the DB. + #[test] + fn f32_to_f64_widening_is_order_preserving_for_non_representable_values() { + // Spread of f32 values that are not "nice" in decimal, straddling 0. + let xs: [f32; 7] = [-0.3, -0.1, -0.0625, 0.0, 0.1, 0.2, 0.3]; + for w in xs.windows(2) { + let (a, b) = (w[0], w[1]); + // f32 strict order matches the widened f64 strict order, bit-for-bit + // on the value the f64 crypto path actually sees. + assert_eq!( + a < b, + (a as f64) < (b as f64), + "widening {a} -> {} reordered relative to {b} -> {}", + a as f64, + b as f64 + ); + // total_cmp (the newtype's Ord source) agrees with the widened cmp. + assert_eq!( + a.total_cmp(&b), + (a as f64).total_cmp(&(b as f64)), + "F4 Ord (total_cmp) disagrees with widened F8 Ord for {a} vs {b}" + ); + } + } } ``` +> **Why this guard, not a DB/oracle test.** The fixture corpus is all exact-in-f32, so neither the fixture-oracle (Task 5) nor the e2e-oracle (Task 6) ever encrypts an f32 whose value is perturbed by widening. The widening contract is a pure arithmetic property of `f32 as f64`, so a `#[cfg(test)]` `#[test]` is the lighter-weight, deterministic place to pin it — no creds, no ZeroKMS round trip. + - [ ] **Step 2: Run to confirm failure** Run: `cargo test -p eql_tests --lib float_value_guards` @@ -489,7 +538,6 @@ impl Default for F4 { } impl std::fmt::Display for F4 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // SQL literal form handled by `to_sql_literal`; Display is the raw value. write!(f, "{}", self.0) } } @@ -530,44 +578,43 @@ impl std::fmt::Display for F8 { Add the `LazyLock` cells, accessors, and impls. `to_sql_literal` must render non-finite values as the Postgres float literal `'Infinity'`/`'-Infinity'` (a bare `inf` is not valid SQL); finite values render via the inner primitive's `Display`, which is a valid SQL float literal. +The value accessors reuse the existing `lazy_values!` materialiser (the same path `numeric` uses — the catalog stays zero-dep, so the parse lives here), each wrapping the parsed primitive in its newtype. This is the only shared-macro reuse; the trait impls below stay hand-written (see the duplication note at the top of this task): + ```rust -/// Typed `F4` fixtures, parsed once from `float4`'s catalog row (the catalog -/// stays zero-dep; the parse lives here). Public so the `eql_v2_float4` fixture -/// module can hand the slice to `scalar_fixture!`. -static FLOAT4_VALUES_CELL: std::sync::LazyLock> = std::sync::LazyLock::new(|| { - eql_scalars::FLOAT4 - .fixtures - .iter() - .map(|f| match f { - eql_scalars::Fixture::Float(s) => F4(s - .parse() - .unwrap_or_else(|e| panic!("invalid float4 catalog fixture {s:?}: {e}"))), - other => panic!("non-float fixture in float4 catalog row: {other:?}"), - }) - .collect() -}); - -/// The `float4` fixture values, in catalog order. -pub fn float4_values() -> &'static [F4] { - &FLOAT4_VALUES_CELL +// `float4`'s value wiring goes through the shared `lazy_values!` materialiser +// (same as `numeric`/`text`), parsing the catalog's `Fixture::Float` strings into +// the `F4` newtype. `float4_values()` is public so the `eql_v2_float4` fixture +// module (emitted by `scalar_types!(fixture_modules)`) can hand the slice to +// `scalar_fixture!`. Rust's `str::parse::` accepts `"inf"`/`"-inf"`/`"nan"`, +// so the ±Inf pivots parse natively (NaN is excluded by the catalog guards). +lazy_values! { + cell = FLOAT4_VALUES_CELL, + accessor = float4_values, + rust_type = F4, + spec = eql_scalars::FLOAT4, + variant = Float, + pg_type = "float4", + parse = |f| match f { + eql_scalars::Fixture::Float(s) => F4(s + .parse() + .unwrap_or_else(|e| panic!("invalid float4 catalog fixture {s:?}: {e}"))), + other => panic!("non-float fixture in float4 catalog row: {other:?}"), + }, } -static FLOAT8_VALUES_CELL: std::sync::LazyLock> = std::sync::LazyLock::new(|| { - eql_scalars::FLOAT8 - .fixtures - .iter() - .map(|f| match f { - eql_scalars::Fixture::Float(s) => F8(s - .parse() - .unwrap_or_else(|e| panic!("invalid float8 catalog fixture {s:?}: {e}"))), - other => panic!("non-float fixture in float8 catalog row: {other:?}"), - }) - .collect() -}); - -/// The `float8` fixture values, in catalog order. -pub fn float8_values() -> &'static [F8] { - &FLOAT8_VALUES_CELL +lazy_values! { + cell = FLOAT8_VALUES_CELL, + accessor = float8_values, + rust_type = F8, + spec = eql_scalars::FLOAT8, + variant = Float, + pg_type = "float8", + parse = |f| match f { + eql_scalars::Fixture::Float(s) => F8(s + .parse() + .unwrap_or_else(|e| panic!("invalid float8 catalog fixture {s:?}: {e}"))), + other => panic!("non-float fixture in float8 catalog row: {other:?}"), + }, } /// Render an f64 as a Postgres float SQL literal. Finite values use the numeric @@ -1103,6 +1150,74 @@ async fn float8_sign_boundary(pool: PgPool) -> anyhow::Result<()> { (`min_pivot()` = `-Inf`, `origin()` = `0.0`, `max_pivot()` = `+Inf` — the monotonic span `-Inf < 0 < +Inf` is exactly the signed-zero boundary this suite exists to cover.) +- [ ] **Step 2b: Add the cross-width byte-identity test (proves the CHANGELOG claim)** + +The CHANGELOG entry (Task 9 Step 1) asserts that, because both widths share the single f64 crypto path, "the ciphertext / ORE term are byte-identical" — but nothing else in the plan exercises it. Add one creds/e2e-gated test that encrypts the SAME value as `F4(x)` and `F8(x as f64)` and asserts the index terms (`hm` equality term, `ob` ORE term) match. `encrypt_store` returns `Vec` whose payload objects carry string `hm`/`ob` fields (verified in `cipherstash.rs` — the `assert_store_shape` helper checks `v`/`c`/`hm`/`ob`/`i`), so the comparison reads those keys directly. Place it in `e2e_oracle.rs` (it already imports `column_config_for`, `encrypt_store`, `EqlPlaintext`, `IndexKind`, `connect_pool`, `ensure_eql_installed`, `super::migrator()`): + +```rust +/// Both float widths encrypt through the SINGLE f64 crypto path +/// (`F4::to_plaintext` widens `self.0 as f64`; `F8::to_plaintext` is the +/// identity), so an f32 value and its exact f64 widening MUST produce identical +/// index terms — this is the byte-identity the CHANGELOG claims. Encrypt the +/// same value both ways (an f32-exact value, so `x as f64` is lossless) and +/// assert the `hm` (HMAC equality) and `ob` (ORE) terms match across widths. +/// Creds/e2e-gated like the rest of this file. +#[test] +fn float4_and_float8_share_index_terms_for_the_same_value() -> Result<()> { + use eql_tests::scalar_domains::{F4, F8}; + + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; + let pool: PgPool = rt.block_on(connect_pool())?; + rt.block_on(ensure_eql_installed(&pool, &super::migrator()))?; + + // f32-exact value: `x as f64` is the same real number, so any term + // difference would be a width artifact, which is exactly what we forbid. + let x: f32 = 2.25; + + let f4_payloads = rt.block_on(async { + let cfg = column_config_for( + &[IndexKind::Unique, IndexKind::Ore], + ::CAST, + )?; + encrypt_store("xwidth_f4", "payload", &[F4(x)], &cfg).await + })?; + let f8_payloads = rt.block_on(async { + let cfg = column_config_for( + &[IndexKind::Unique, IndexKind::Ore], + ::CAST, + )?; + encrypt_store("xwidth_f8", "payload", &[F8(x as f64)], &cfg).await + })?; + + // Pull a string index term from the EQL payload JSON (`hm` / `ob`). + let term = |p: &serde_json::Value, key: &str| -> Result { + p.get(key) + .and_then(serde_json::Value::as_str) + .map(str::to_string) + .ok_or_else(|| anyhow::anyhow!("payload missing string `{key}`: {p}")) + }; + + // HMAC equality term: identical plaintext + key => identical hm, so the two + // widths are equality-interchangeable at the term level. + assert_eq!( + term(&f4_payloads[0], "hm")?, + term(&f8_payloads[0], "hm")?, + "float4 and float8 of the same value must share the hm equality term" + ); + // ORE term: same f64 input => same ORE ciphertext, so ordering is identical. + assert_eq!( + term(&f4_payloads[0], "ob")?, + term(&f8_payloads[0], "ob")?, + "float4 and float8 of the same value must share the ob ORE term" + ); + Ok(()) +} +``` + +> **Implementer note:** confirm the `hm`/`ob` terms are deterministic across two independent `encrypt_store` calls (same plaintext + same keyset). They are — `hm` is a keyed HMAC of the plaintext and `ob` is the ORE encoding, both pure functions of plaintext+key (the `cipherstash.rs` `encrypt_store_batch_distinct_plaintexts_yield_distinct_hm` live test relies on the same determinism). If the SDK ever salts these per-call, downgrade the assertion to "decrypt-equal / order-equal through the `eql_v3.float8`/`float4` domains" instead of raw term-string equality, and note it in the CHANGELOG. The value is encrypted fresh (not fetched from the fixture table), so it need not be a catalog fixture; `2.25` is chosen only because it is exactly representable in f32, making `x as f64` lossless so any term mismatch is unambiguously a width artifact. + - [ ] **Step 3: Compile both binaries** Run: `cargo test -p eql_tests --test encrypted_domain --features proptest-e2e --no-run` @@ -1111,7 +1226,7 @@ Expected: compiles. The `e2e_oracle.rs` suite is `#[cfg(feature = "proptest-e2e" - [ ] **Step 4: Run the sign-boundary tests (fixtures present)** Run: `cargo test -p eql_tests --test encrypted_domain -- signed::float` -Expected: PASS — `float4_sign_boundary`, `float8_sign_boundary` (requires the `eql_v2_float4`/`eql_v2_float8` fixtures from Task 5 Step 4). e2e runs under `--features proptest-e2e` with creds (CI); locally, the compile in Step 3 is the gate. +Expected: PASS — `float4_sign_boundary`, `float8_sign_boundary` (requires the `eql_v2_float4`/`eql_v2_float8` fixtures from Task 5 Step 4). e2e runs under `--features proptest-e2e` with creds (CI); locally, the compile in Step 3 is the gate. The cross-width byte-identity test (Step 2b) is part of the e2e binary — run it under creds with `cargo test -p eql_tests --test encrypted_domain --features proptest-e2e -- float4_and_float8_share_index_terms`; it asserts the CHANGELOG's byte-identity claim. - [ ] **Step 5: Commit** @@ -1127,6 +1242,8 @@ git commit -m "test(v3): wire float4/float8 into e2e oracle + sign-boundary suit A hand-written behavioural suite that encrypts the special values **fresh** at test time so NaN never enters the shared fixture table. Registered via `#[path]` mod **outside** `scalars::` (like `text_match`/`signed`) so it does not pollute the matrix-inventory snapshot. Exact NaN eq/order outcomes are **discovered-and-locked on first run** — the test asserts the deterministic outcome observed, with comments that it is an artifact of the canonical bit pattern, not a guarantee. +> **Hardening note — the `-0.0 → +0.0` assertion pins the `orderable-bytes` ORE path.** The `negative_zero_and_positive_zero_compare_equal_and_share_ore` test only holds because the float ORE encoder in use canonicalises `-0.0` to `+0.0` before encoding — confirmed in `orderable-bytes` `primitive.rs` (`ToOrderableBytes for f32`/`f64`: `let value = if *self == -0.0 { 0.0 } else { *self };`). A **dormant** alternative encoder, `cllw-ore` `impls/primitives.rs`, explicitly **distinguishes** them ("`−0.0` ciphertext is strictly less than `+0.0`") — if a future change routes float ORE through that path, this test flips from "equal" to "`-0.0 < +0.0`". The test is the canary: keep its comment pointing at the orderable-bytes canonicalisation so a failure is read as "the ORE path changed", not "the test is wrong". (`-0.0`/`+0.0` are also excluded as a duplicate fixture pair precisely because of this canonicalisation — see Global Constraints.) + **Files:** - Create: `tests/sqlx/tests/encrypted_domain/float_special.rs` - Modify: `tests/sqlx/tests/encrypted_domain.rs` (`#[path]` mod registration) @@ -1375,13 +1492,12 @@ git commit -m "test(v3): commit float4/float8 codegen reference baselines" --- -## Task 9: Changelog + upgrade note + full test pass +## Task 9: Changelog + full test pass Document the user-facing addition and run the full PostgreSQL test matrix. **Files:** - Modify: `CHANGELOG.md` (`[Unreleased]` → `Added`) -- Modify: `docs/upgrading/v2.4.md` (numbered upgrade note) **Interfaces:** none (docs + verification). @@ -1390,21 +1506,17 @@ Document the user-facing addition and run the full PostgreSQL test matrix. In `CHANGELOG.md`, under `## [Unreleased]` → `### Added`, add an entry matching the tone/density of the existing `eql_v3.numeric` / `eql_v3.timestamptz` entries (one dense paragraph, lead with the user-visible fact, then "Why.", then a PR link placeholder): ```markdown -- **`eql_v3.float4` / `eql_v3.float8` encrypted-domain type families (ordered).** Four jsonb-backed domains each for encrypted `real` / `double precision` columns — `eql_v3.float4` / `eql_v3.float8` (storage-only), `eql_v3._eq` (`=` / `<>` via HMAC), and `eql_v3._ord` / `eql_v3._ord_ore` (also `<` `<=` `>` `>=`, `MIN` / `MAX` via 8-block ORE) — generated from the `float4` / `float8` rows in `eql-scalars::CATALOG` by the same materializer as the `eql_v3.int4` reference. Both widths encrypt through a single f64 crypto path (`Plaintext::Float`): a `real` is widened to f64 before encryption (exact and monotonic), so `float4` vs `float8` is purely a Postgres-surface distinction and the ciphertext / ORE term are byte-identical. Ordering is correct for all non-NaN values via the standard monotonic IEEE-754 byte mapping (`f64::ENCODED_LEN == 8`, same as `int8`); `-0.0` canonicalizes to `+0.0` and `±Inf` order correctly. NaN is unordered and unspecified in the encoder — it can be encrypted and stored but is not given a meaningful comparison guarantee (any NaN rejection is client-side). Index via a functional index on the `eql_v3.eq_term` / `eql_v3.ord_term` extractors, not an operator class on the domain. Why: a type-safe, per-capability encrypted IEEE-754 float column, closing the gap for `real` / `double` columns that had no v3 equivalent (the v3 `numeric` family is arbitrary-precision decimal, not binary float). See the U-NNN upgrade note. ([#NNN](https://github.com/cipherstash/encrypt-query-language/pull/NNN)) +- **`eql_v3.float4` / `eql_v3.float8` encrypted-domain type families (ordered).** Four jsonb-backed domains each for encrypted `real` / `double precision` columns — `eql_v3.float4` / `eql_v3.float8` (storage-only), `eql_v3._eq` (`=` / `<>` via HMAC), and `eql_v3._ord` / `eql_v3._ord_ore` (also `<` `<=` `>` `>=`, `MIN` / `MAX` via 8-block ORE) — generated from the `float4` / `float8` rows in `eql-scalars::CATALOG` by the same materializer as the `eql_v3.int4` reference. Both widths encrypt through a single f64 crypto path (`Plaintext::Float`): a `real` is widened to f64 before encryption (exact and monotonic), so `float4` vs `float8` is purely a Postgres-surface distinction and the ciphertext / ORE term are byte-identical. Ordering is correct for all non-NaN values via the standard monotonic IEEE-754 byte mapping (`f64::ENCODED_LEN == 8`, same as `int8`); `-0.0` canonicalizes to `+0.0` and `±Inf` order correctly. NaN is unordered and unspecified in the encoder — it can be encrypted and stored but is not given a meaningful comparison guarantee (any NaN rejection is client-side). Index via a functional index on the `eql_v3.eq_term` / `eql_v3.ord_term` extractors, not an operator class on the domain. Why: a type-safe, per-capability encrypted IEEE-754 float column, closing the gap for `real` / `double` columns that had no v3 equivalent (the v3 `numeric` family is arbitrary-precision decimal, not binary float). ([#NNN](https://github.com/cipherstash/encrypt-query-language/pull/NNN)) ``` -(Replace `#NNN`/`U-NNN` with the real PR number and the note id assigned in Step 2.) +(Replace `#NNN` with the real PR number. The IEEE-754 caveats — NaN has no comparison guarantee; `-0.0` and `+0.0` are equal; `float4` round-trips through f64 — are folded inline into this entry. No separate `docs/upgrading/` note is created: this is an additive `eql_v3` change, not an `eql_v2` release with its own upgrade guide.) -- [ ] **Step 2: Add the upgrade note** - -In `docs/upgrading/v2.4.md`, add a numbered note (next free `U-NNN`) capturing the float-specific caveats callers should know: NaN has no comparison guarantee (encrypts/stores but is not searchable-ordered meaningfully; reject client-side if undesired); `-0.0` and `+0.0` are equal (IEEE-consistent); `float4` columns round-trip through f64 (use values representable in f32 or accept widening). Cross-link the `Added` entry to it. Match the existing note format in that file (TL;DR, applies-to, action). - -- [ ] **Step 3: Run the full SQLx + PostgreSQL matrix** +- [ ] **Step 2: Run the full SQLx + PostgreSQL matrix** Run: `mise run test` Expected: PASS — the full suite (build, reset, SQLx) including all float matrix tests (`scalars::float4::*`, `scalars::float8::*`), the fixture/e2e oracles, sign-boundary, and `float_special` (where creds allow). Optionally repeat against a specific version: `mise run test --postgres 17`. -- [ ] **Step 4: Final verification sweep** +- [ ] **Step 3: Final verification sweep** Run the canonical order once more to confirm nothing regressed: ```bash @@ -1415,11 +1527,11 @@ mise run test:self_contained_v3 ``` Expected: all PASS. -- [ ] **Step 5: Commit** +- [ ] **Step 4: Commit** ```bash -git add CHANGELOG.md docs/upgrading/v2.4.md -git commit -m "docs(v3): changelog + upgrade note for float4/float8 encrypted domains" +git add CHANGELOG.md +git commit -m "docs(v3): changelog entry for float4/float8 encrypted domains" ``` --- @@ -1429,7 +1541,7 @@ git commit -m "docs(v3): changelog + upgrade note for float4/float8 encrypted do **Spec coverage (design groups A–D):** - A. Catalog/declarative — Task 1 (kind/fixture/specs/CATALOG, kind.rs/fixture.rs arms, catalog tests) + Task 2 (`scalar_types.rs` line is in Task 4; `scalar_domains.rs` newtypes/accessors/impls/guards/test-lists in Task 2). ✓ - B. New-kind plumbing — Task 4 (`is_float_token` + router arm), Task 3 (`eql_plaintext.rs`), Task 4 (`scalar_fixture.rs` float arm), Task 4 (`scalar_types.rs`), Task 2 (`scalar_domains.rs` newtypes, accessors, impls, guards, oracle/pivot/arbitrary lists). ✓ -- C. Tests — Task 5 (fixture oracle), Task 6 (e2e oracle), Task 7 (`float_special` + mod registration), Task 6 (signed). Matrix inventory snapshot unchanged (token-normalized) — verified in Tasks 4/7. ✓ +- C. Tests — Task 5 (fixture oracle), Task 6 (e2e oracle + cross-width byte-identity, Step 2b), Task 7 (`float_special` + mod registration), Task 6 (signed). The f32→f64 widening property is pinned by a pure-Rust guard in Task 2 Step 1 (`f32_to_f64_widening_is_order_preserving_for_non_representable_values`). Matrix inventory snapshot unchanged (token-normalized) — verified in Tasks 4/7. ✓ - D. Artefacts & docs — Task 8 (reference baselines, build, self-contained gate), Task 9 (CHANGELOG + upgrade note). ✓ **Flagged risks folded in as checkpoints:** @@ -1447,4 +1559,7 @@ git commit -m "docs(v3): changelog + upgrade note for float4/float8 encrypted do 3. **`scalar_types.rs` newtype path resolution.** The proc-macro expands the type list into three different crate targets; `crate::scalar_domains::F4` may not resolve at every call site. Plan Task 4 Step 6 carries a fallback (`use eql_tests::scalar_domains::{F4, F8};` at call sites). Verify at first compile. 4. **`float4` cast.** The design's crypto facts note `real`/`double`/`float` all map to `ColumnType::Float`. This plan uses `Cast::REAL` for `float4` and `Cast::DOUBLE` for `float8` (both yield identical f64 ciphertext) with the matching plaintext-column SQL types `real` / `double precision`. If the float8 column should instead use the bare `float` cast literally, it is interchangeable; flagged for confirmation. 5. **No per-type fixture files.** The design lists `eql_v2_float*` modules; in this codebase those are macro-emitted (not standalone `.rs` files) — Task 4 Step 7 is a checkpoint to confirm `fixtures/mod.rs` uses `scalar_types!(fixture_modules)` and skip file creation accordingly. +6. **Cross-width comparison is unsupported (decided, not under-specified).** `eql_v3.float4` and `eql_v3.float8` are separate domains with no cross-type operator — exactly as `int4`/`int8` relate. Verified against the codegen operator renderer (`operator_surface.rs` / `generate.rs`): every overload is `(Domain, Domain)` / `(Domain, jsonb)` / `(jsonb, Domain)` on a single per-domain type. Stated in the architecture preamble; no test added (int-width cross-comparison is not tested either — the operator does not exist). +7. **`float_special` `-0.0` assertion pins the `orderable-bytes` ORE path.** Verified that `orderable-bytes` canonicalises `-0.0 → +0.0` while the dormant `cllw-ore` encoder distinguishes them; the Task 7 hardening note keeps the test as the canary if the encoder path ever changes. +8. **Inter-task compile coupling (Task 1 ↔ Task 3).** Adding `F32`/`F64` to `ScalarKind` breaks the exhaustive `match`es in `eql_plaintext.rs` until Task 3 lands the arms — so `eql_tests` does not compile between the two tasks. Documented in Global Constraints + a Task 1 Step 9 note; Task 1 is verified with `cargo test -p eql-scalars` in isolation. ``` \ No newline at end of file From c78b7a4834c8e9e832e633cdd3a055da2043c60c Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 20:08:23 +1000 Subject: [PATCH 5/6] =?UTF-8?q?docs/test(v3):=20float=20review=20follow-up?= =?UTF-8?q?s=20=E2=80=94=20dyadic=20fixture=20invariant,=20NaN=20caveat,?= =?UTF-8?q?=20order=20tripwire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - eql-scalars: correct the FLOAT4_FIXTURES comment — the values are dyadic rationals (n/2^k), not 'powers of two and halves'; add a keep-it-dyadic warning so a non-f32-exact fixture (e.g. 0.1) can't silently desync the oracle. - eql-types: document NaN/-0.0/+-Inf special-value behaviour on the float8 module (and point float4 at it) — NaN is never rejected server-side, so the caller-facing 'reject NaN client-side' guidance lives next to the types. - float_special: add nan_order_position_is_deterministic_and_total, a tripwire locking the total+deterministic order the Block-ORE index relies on (without pinning NaN's unspecified direction). - Drop the dangling reference to the removed U-001 upgrade note. --- crates/eql-scalars/src/lib.rs | 8 ++- crates/eql-types/src/v3/float4.rs | 4 ++ crates/eql-types/src/v3/float8.rs | 14 +++++ .../tests/encrypted_domain/float_special.rs | 53 +++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/crates/eql-scalars/src/lib.rs b/crates/eql-scalars/src/lib.rs index 3773ee46..899573c6 100644 --- a/crates/eql-scalars/src/lib.rs +++ b/crates/eql-scalars/src/lib.rs @@ -507,8 +507,12 @@ pub const TEXT: ScalarSpec = ScalarSpec { /// `float4` fixture plaintexts — IEEE-754 strings parsed into `f32` in the SQLx /// harness (the catalog stays zero-dep). EVERY value is exactly representable in -/// f32 (powers of two and halves), so the `real` round-trip is lossless and the -/// f32→f64 widening before encryption is exact. The three pivots MUST be present +/// f32 — each is a dyadic rational `n/2^k` (e.g. `2.25 = 9/4`, `0.25 = 1/4`, +/// `1024 = 2^10`), the value class `real` stores losslessly — so the `real` +/// round-trip is lossless and the f32→f64 widening before encryption is exact. +/// Keep new fixtures dyadic: a value like `0.1` is NOT f32-exact, and the +/// oracle's expected order (parsed `f32`) would then disagree with the value the +/// `real` column actually rounds to. The three pivots MUST be present /// verbatim: `"-inf"` (min_pivot), `"0"` (origin/mid), `"inf"` (max_pivot). /// NaN and `-0.0` are deliberately excluded (see the `float_special` suite). /// Distinctness is enforced by `Fixture::Float` (above) and its guard test. diff --git a/crates/eql-types/src/v3/float4.rs b/crates/eql-types/src/v3/float4.rs index 10d841f5..4af55023 100644 --- a/crates/eql-types/src/v3/float4.rs +++ b/crates/eql-types/src/v3/float4.rs @@ -8,6 +8,10 @@ //! wire shape here is identical to [`crate::v3::float8`] — an 8-block `ob` term //! (`f64::ENCODED_LEN == 8`, same as `int8`). `float4` vs `float8` is purely a //! Postgres-surface distinction (column type, domain name). +//! +//! Special-value behaviour (`-0.0`, `±Inf`, and the **NaN is not rejected +//! server-side — reject it client-side** caveat) is identical to `float8`; see +//! [`crate::v3::float8`] for the full note. use schemars::{schema::RootSchema, schema_for}; diff --git a/crates/eql-types/src/v3/float8.rs b/crates/eql-types/src/v3/float8.rs index fd8c2432..de2ebba3 100644 --- a/crates/eql-types/src/v3/float8.rs +++ b/crates/eql-types/src/v3/float8.rs @@ -7,6 +7,20 @@ //! (`Plaintext::Float`), so the wire shape is identical to //! [`crate::v3::float4`] — an 8-block `ob` term (`f64::ENCODED_LEN == 8`, same //! as `int8`). +//! +//! ## Special values (caller-facing) +//! +//! `-0.0` canonicalizes to `+0.0` (equal under `=`, IEEE-consistent) and +//! `±Inf` order correctly (`-Inf < finite < +Inf`). **NaN is unordered and +//! unspecified in the encoder**: it can be encrypted, stored, and pass the +//! domain CHECK, but it carries **no comparison guarantee** and does NOT follow +//! IEEE semantics (where NaN compares false against everything). The domain +//! CHECK validates only the envelope — it cannot inspect the ciphertext — so a +//! NaN payload is never rejected server-side. **Reject NaN client-side before +//! encryption** if your column must not contain it; otherwise a NaN row sorts +//! at an arbitrary (but deterministic) position in an encrypted range scan +//! rather than being excluded the way native Postgres `double precision` would. +//! See the `float_special` regression suite for the locked behaviour. use schemars::{schema::RootSchema, schema_for}; diff --git a/tests/sqlx/tests/encrypted_domain/float_special.rs b/tests/sqlx/tests/encrypted_domain/float_special.rs index 263cfe33..f7af74b0 100644 --- a/tests/sqlx/tests/encrypted_domain/float_special.rs +++ b/tests/sqlx/tests/encrypted_domain/float_special.rs @@ -130,3 +130,56 @@ async fn infinities_order_correctly() -> Result<()> { assert!(ord_cmp(&pool, &p[0], "<", &p[2]).await?, "-Inf < +Inf"); Ok(()) } + +#[tokio::test] +async fn nan_order_position_is_deterministic_and_total() -> Result<()> { + // TRIPWIRE for encoder drift — NOT a direction guarantee. + // + // NaN is "unordered and unspecified" by design, so we deliberately do NOT + // pin WHERE NaN sorts relative to finite / ±Inf values (that position is an + // encoder artifact and may change). But the Block-ORE index the `_ord` + // domain rides on requires a *total, deterministic* order: the same + // plaintext must always land at the same position, and every pair must + // resolve to exactly one of `<` / `=` / `>`. If a future encoder change + // makes NaN's position non-deterministic (same bits, different sort slot -> + // btree corruption) or non-total (a comparison that follows IEEE and returns + // false both ways), this fails loudly. The NaN==NaN equality artifact is + // locked separately in `two_encryptions_of_same_nan_bits_compare_equal`; + // this guards the ORDER side of the same deterministic-terms property. + let pool = setup().await?; + // Two independent encryptions of canonical NaN, plus a spread of references. + let p = encrypt_specials(&[ + F8(f64::NAN), // 0: NaN (encryption A) + F8(f64::NAN), // 1: NaN (encryption B) + F8(f64::NEG_INFINITY), // 2 + F8(0.0), // 3 + F8(f64::INFINITY), // 4 + ]) + .await?; + let (nan_a, nan_b) = (&p[0], &p[1]); + + for (label, r) in [("-Inf", &p[2]), ("0", &p[3]), ("+Inf", &p[4])] { + let lt = ord_cmp(&pool, nan_a, "<", r).await?; + let eq = ord_cmp(&pool, nan_a, "=", r).await?; + let gt = ord_cmp(&pool, nan_a, ">", r).await?; + // Totality: exactly one of < = > holds (NaN is NOT IEEE-incomparable here). + assert_eq!( + [lt, eq, gt].iter().filter(|b| **b).count(), + 1, + "NaN vs {label} is not a total order: (<, =, >) = ({lt}, {eq}, {gt})" + ); + // Determinism: a second independent NaN encryption lands identically. + let (lt_b, eq_b, gt_b) = ( + ord_cmp(&pool, nan_b, "<", r).await?, + ord_cmp(&pool, nan_b, "=", r).await?, + ord_cmp(&pool, nan_b, ">", r).await?, + ); + assert_eq!( + (lt, eq, gt), + (lt_b, eq_b, gt_b), + "NaN's order position vs {label} is not stable across re-encryption \ + (deterministic index terms broken)" + ); + } + Ok(()) +} From 58e07492e1c8a6df4f7650672380154b555b1666 Mon Sep 17 00:00:00 2001 From: Toby Hede Date: Fri, 19 Jun 2026 22:04:03 +1000 Subject: [PATCH 6/6] fix(v3): hand-write F4/F8 PartialEq via total_cmp for Eq/Ord consistency Derived IEEE PartialEq (NaN != NaN, +0.0 == -0.0) was inconsistent with the manual Eq/Ord impls built on total_cmp (NaN == NaN, +0.0 != -0.0), breaking Eq's reflexivity contract and Ord/PartialEq equality agreement. --- tests/sqlx/src/scalar_domains.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/sqlx/src/scalar_domains.rs b/tests/sqlx/src/scalar_domains.rs index 8cf43ab2..b8071309 100644 --- a/tests/sqlx/src/scalar_domains.rs +++ b/tests/sqlx/src/scalar_domains.rs @@ -799,10 +799,18 @@ mod text_value_tests { /// `#[derive(sqlx::Type)]` + `#[sqlx(transparent)]` already generates the /// delegating `Type` AND `Decode` (and `Encode`) impls for the newtype, so we do /// NOT also `#[derive(sqlx::Decode)]` — that would be a conflicting impl. -#[derive(Debug, Clone, Copy, PartialEq, sqlx::Type)] +#[derive(Debug, Clone, Copy, sqlx::Type)] #[sqlx(transparent)] pub struct F4(pub f32); +// `PartialEq` is hand-written via `total_cmp` (not derived) so it stays +// consistent with the `Ord`/`Eq` impls below: derived IEEE equality breaks +// `Eq`'s reflexivity for NaN and disagrees with `total_cmp` on signed zero. +impl PartialEq for F4 { + fn eq(&self, other: &Self) -> bool { + self.0.total_cmp(&other.0) == std::cmp::Ordering::Equal + } +} impl Eq for F4 {} impl Ord for F4 { fn cmp(&self, other: &Self) -> std::cmp::Ordering { @@ -830,10 +838,16 @@ impl std::fmt::Display for F4 { /// `double precision`, `Default = F8(0.0)`. Like `F4`, the transparent /// `sqlx::Type` derive also supplies `Decode`/`Encode`, so they are not derived /// separately. -#[derive(Debug, Clone, Copy, PartialEq, sqlx::Type)] +#[derive(Debug, Clone, Copy, sqlx::Type)] #[sqlx(transparent)] pub struct F8(pub f64); +// `PartialEq` is hand-written via `total_cmp` (not derived); see `F4` above. +impl PartialEq for F8 { + fn eq(&self, other: &Self) -> bool { + self.0.total_cmp(&other.0) == std::cmp::Ordering::Equal + } +} impl Eq for F8 {} impl Ord for F8 { fn cmp(&self, other: &Self) -> std::cmp::Ordering {