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.
* **Equality / Inequality**: `{"$eq": value}`, `{"$ne": value}` automatically map to `=` and `!=`.
* **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.
* **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.

View File

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

View File

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