in, nin to of, nof for go and dart generator compatibility

This commit is contained in:
2026-04-17 02:24:03 -04:00
parent 87a845e85a
commit 509194b55f
3 changed files with 27 additions and 27 deletions

View File

@ -234,7 +234,7 @@ The Queryer transforms Postgres into a pre-compiled Semantic Query Engine, desig
* **Dynamic Filtering**: Binds parameters natively through `cue.filters` objects. The queryer enforces a strict, structured, MongoDB-style operator syntax to map incoming JSON request constraints directly to their originating structural table columns. Filters support both flat path notation (e.g., `"contacts/is_primary": {...}`) and deeply nested recursive JSON structures (e.g., `{"contacts": {"is_primary": {...}}}`). The queryer recursively traverses and flattens these structures at AST compilation time. * **Dynamic Filtering**: Binds parameters natively through `cue.filters` objects. The queryer enforces a strict, structured, MongoDB-style operator syntax to map incoming JSON request constraints directly to their originating structural table columns. Filters support both flat path notation (e.g., `"contacts/is_primary": {...}`) and deeply nested recursive JSON structures (e.g., `{"contacts": {"is_primary": {...}}}`). The queryer recursively traverses and flattens these structures at AST compilation time.
* **Equality / Inequality**: `{"$eq": value}`, `{"$ne": value}` automatically map to `=` and `!=`. * **Equality / Inequality**: `{"$eq": value}`, `{"$ne": value}` automatically map to `=` and `!=`.
* **Comparison**: `{"$gt": ...}`, `{"$gte": ...}`, `{"$lt": ...}`, `{"$lte": ...}` directly compile to Postgres comparison operators (`> `, `>=`, `<`, `<=`). * **Comparison**: `{"$gt": ...}`, `{"$gte": ...}`, `{"$lt": ...}`, `{"$lte": ...}` directly compile to Postgres comparison operators (`> `, `>=`, `<`, `<=`).
* **Array Inclusion**: `{"$in": [values]}`, `{"$nin": [values]}` use native `jsonb_array_elements_text()` bindings to enforce `IN` and `NOT IN` logic without runtime SQL injection risks. * **Array Inclusion**: `{"$of": [values]}`, `{"$nof": [values]}` use native `jsonb_array_elements_text()` bindings to enforce `IN` and `NOT IN` logic without runtime SQL injection risks.
* **Text Matching (ILIKE)**: Evaluates `$eq` or `$ne` against string fields containing the `%` character natively into Postgres `ILIKE` and `NOT ILIKE` partial substring matches. * **Text Matching (ILIKE)**: Evaluates `$eq` or `$ne` against string fields containing the `%` character natively into Postgres `ILIKE` and `NOT ILIKE` partial substring matches.
* **Type Casting**: Safely resolves dynamic combinations by casting values instantly into the physical database types mapped in the schema (e.g. parsing `uuid` bindings to `::uuid`, formatting DateTimes to `::timestamptz`, and numbers to `::numeric`). * **Type Casting**: Safely resolves dynamic combinations by casting values instantly into the physical database types mapped in the schema (e.g. parsing `uuid` bindings to `::uuid`, formatting DateTimes to `::timestamptz`, and numbers to `::numeric`).
* **Polymorphic SQL Generation (`family`)**: Compiles `family` properties by analyzing the **Physical Database Variations**, *not* the schema descendants. * **Polymorphic SQL Generation (`family`)**: Compiles `family` properties by analyzing the **Physical Database Variations**, *not* the schema descendants.

View File

@ -1199,10 +1199,10 @@
"id": { "id": {
"$eq": "123e4567-e89b-12d3-a456-426614174000", "$eq": "123e4567-e89b-12d3-a456-426614174000",
"$ne": "123e4567-e89b-12d3-a456-426614174001", "$ne": "123e4567-e89b-12d3-a456-426614174001",
"$in": [ "$of": [
"123e4567-e89b-12d3-a456-426614174000" "123e4567-e89b-12d3-a456-426614174000"
], ],
"$nin": [ "$nof": [
"123e4567-e89b-12d3-a456-426614174001" "123e4567-e89b-12d3-a456-426614174001"
] ]
}, },
@ -1241,9 +1241,9 @@
" AND entity_1.created_at <= ($7#>>'{}')::timestamptz", " AND entity_1.created_at <= ($7#>>'{}')::timestamptz",
" AND entity_1.created_at != ($8#>>'{}')::timestamptz", " AND entity_1.created_at != ($8#>>'{}')::timestamptz",
" AND entity_1.id = ($9#>>'{}')::uuid", " AND entity_1.id = ($9#>>'{}')::uuid",
" AND entity_1.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($10#>>'{}')::jsonb))", " AND entity_1.id != ($10#>>'{}')::uuid",
" AND entity_1.id != ($11#>>'{}')::uuid", " AND entity_1.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($11#>>'{}')::jsonb))",
" AND entity_1.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($12#>>'{}')::jsonb))", " AND entity_1.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($12#>>'{}')::jsonb))",
")))" ")))"
] ]
] ]
@ -1448,14 +1448,14 @@
"$eq": 30, "$eq": 30,
"$gt": 20, "$gt": 20,
"$gte": 20, "$gte": 20,
"$in": [ "$of": [
30, 30,
40 40
], ],
"$lt": 50, "$lt": 50,
"$lte": 50, "$lte": 50,
"$ne": 25, "$ne": 25,
"$nin": [ "$nof": [
1, 1,
2 2
] ]
@ -1481,24 +1481,24 @@
"$eq": "Jane%", "$eq": "Jane%",
"$gt": "A", "$gt": "A",
"$gte": "A", "$gte": "A",
"$in": [ "$of": [
"Jane", "Jane",
"John" "John"
], ],
"$lt": "Z", "$lt": "Z",
"$lte": "Z", "$lte": "Z",
"$ne": "Doe", "$ne": "Doe",
"$nin": [ "$nof": [
"Bob" "Bob"
] ]
}, },
"id": { "id": {
"$eq": "00000000-0000-0000-0000-000000000001", "$eq": "00000000-0000-0000-0000-000000000001",
"$in": [ "$of": [
"00000000-0000-0000-0000-000000000001" "00000000-0000-0000-0000-000000000001"
], ],
"$ne": "00000000-0000-0000-0000-000000000002", "$ne": "00000000-0000-0000-0000-000000000002",
"$nin": [ "$nof": [
"00000000-0000-0000-0000-000000000002" "00000000-0000-0000-0000-000000000002"
] ]
}, },
@ -1677,11 +1677,11 @@
" AND person_1.age = ($1#>>'{}')::numeric", " AND person_1.age = ($1#>>'{}')::numeric",
" AND person_1.age > ($2#>>'{}')::numeric", " AND person_1.age > ($2#>>'{}')::numeric",
" AND person_1.age >= ($3#>>'{}')::numeric", " AND person_1.age >= ($3#>>'{}')::numeric",
" AND person_1.age IN (SELECT value::numeric FROM jsonb_array_elements_text(($4#>>'{}')::jsonb))", " AND person_1.age < ($4#>>'{}')::numeric",
" AND person_1.age < ($5#>>'{}')::numeric", " AND person_1.age <= ($5#>>'{}')::numeric",
" AND person_1.age <= ($6#>>'{}')::numeric", " AND person_1.age != ($6#>>'{}')::numeric",
" AND person_1.age != ($7#>>'{}')::numeric", " AND person_1.age NOT IN (SELECT value::numeric FROM jsonb_array_elements_text(($7#>>'{}')::jsonb))",
" AND person_1.age NOT IN (SELECT value::numeric FROM jsonb_array_elements_text(($8#>>'{}')::jsonb))", " AND person_1.age IN (SELECT value::numeric FROM jsonb_array_elements_text(($8#>>'{}')::jsonb))",
" AND entity_3.archived = ($9#>>'{}')::boolean", " AND entity_3.archived = ($9#>>'{}')::boolean",
" AND entity_3.archived != ($10#>>'{}')::boolean", " AND entity_3.archived != ($10#>>'{}')::boolean",
" AND entity_3.created_at = ($12#>>'{}')::timestamptz", " AND entity_3.created_at = ($12#>>'{}')::timestamptz",
@ -1693,15 +1693,15 @@
" AND person_1.first_name ILIKE $18#>>'{}'", " AND person_1.first_name ILIKE $18#>>'{}'",
" AND person_1.first_name > ($19#>>'{}')", " AND person_1.first_name > ($19#>>'{}')",
" AND person_1.first_name >= ($20#>>'{}')", " AND person_1.first_name >= ($20#>>'{}')",
" AND person_1.first_name IN (SELECT value FROM jsonb_array_elements_text(($21#>>'{}')::jsonb))", " AND person_1.first_name < ($21#>>'{}')",
" AND person_1.first_name < ($22#>>'{}')", " AND person_1.first_name <= ($22#>>'{}')",
" AND person_1.first_name <= ($23#>>'{}')", " AND person_1.first_name NOT ILIKE $23#>>'{}'",
" AND person_1.first_name NOT ILIKE $24#>>'{}'", " AND person_1.first_name NOT IN (SELECT value FROM jsonb_array_elements_text(($24#>>'{}')::jsonb))",
" AND person_1.first_name NOT IN (SELECT value FROM jsonb_array_elements_text(($25#>>'{}')::jsonb))", " AND person_1.first_name IN (SELECT value FROM jsonb_array_elements_text(($25#>>'{}')::jsonb))",
" AND entity_3.id = ($26#>>'{}')::uuid", " AND entity_3.id = ($26#>>'{}')::uuid",
" AND entity_3.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($27#>>'{}')::jsonb))", " AND entity_3.id != ($27#>>'{}')::uuid",
" AND entity_3.id != ($28#>>'{}')::uuid", " AND entity_3.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($28#>>'{}')::jsonb))",
" AND entity_3.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($29#>>'{}')::jsonb))", " AND entity_3.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($29#>>'{}')::jsonb))",
" AND person_1.last_name ILIKE $30#>>'{}'", " AND person_1.last_name ILIKE $30#>>'{}'",
" AND person_1.last_name NOT ILIKE $31#>>'{}')))" " AND person_1.last_name NOT ILIKE $31#>>'{}')))"
] ]

View File

@ -717,8 +717,8 @@ impl<'a> Compiler<'a> {
let param_index = i + 1; let param_index = i + 1;
let p_val = format!("${}#>>'{{}}'", param_index); let p_val = format!("${}#>>'{{}}'", param_index);
if op == "$in" || op == "$nin" { if op == "$of" || op == "$nof" {
let sql_op = if op == "$in" { "IN" } else { "NOT IN" }; let sql_op = if op == "$of" { "IN" } else { "NOT IN" };
let subquery = format!( let subquery = format!(
"(SELECT value{} FROM jsonb_array_elements_text(({})::jsonb))", "(SELECT value{} FROM jsonb_array_elements_text(({})::jsonb))",
cast, p_val cast, p_val