diff --git a/fixtures/queryer.json b/fixtures/queryer.json index 8d16410..7d9ae2e 100644 --- a/fixtures/queryer.json +++ b/fixtures/queryer.json @@ -367,7 +367,8 @@ "archived", "created_at", "rating", - "tags" + "tags", + "labels" ], "grouped_fields": { "entity": [ @@ -384,7 +385,8 @@ "last_name", "age", "rating", - "tags" + "tags", + "labels" ] }, "field_types": { @@ -397,7 +399,8 @@ "age": "numeric", "created_at": "timestamptz", "rating": "float8", - "tags": "jsonb" + "tags": "jsonb", + "labels": "jsonb" }, "schemas": { "person": { @@ -420,6 +423,16 @@ "items": { "type": "string" } + }, + "labels": { + "type": [ + "array" + ], + "items": { + "type": [ + "string" + ] + } } } }, @@ -440,6 +453,16 @@ "items": { "type": "string" } + }, + "labels": { + "type": [ + "array" + ], + "items": { + "type": [ + "string" + ] + } } } }, @@ -508,6 +531,16 @@ "items": { "type": "string" } + }, + "labels": { + "type": [ + "array" + ], + "items": { + "type": [ + "string" + ] + } } } } @@ -1325,7 +1358,8 @@ " 'last_name', person_3.last_name,", " 'age', person_3.age,", " 'rating', person_3.rating,", - " 'tags', person_3.tags", + " 'tags', person_3.tags,", + " 'labels', person_3.labels", " )", " FROM agreego.entity entity_1", " JOIN agreego.organization organization_2", @@ -1357,6 +1391,7 @@ " 'age', person_3.age,", " 'rating', person_3.rating,", " 'tags', person_3.tags,", + " 'labels', person_3.labels,", " 'phone_numbers', (", " SELECT COALESCE(jsonb_agg(jsonb_build_object(", " 'id', entity_4.id,", @@ -1609,6 +1644,7 @@ " 'age', person_3.age,", " 'rating', person_3.rating,", " 'tags', person_3.tags,", + " 'labels', person_3.labels,", " 'phone_numbers', (", " SELECT COALESCE(jsonb_agg(jsonb_build_object(", " 'id', entity_4.id,", @@ -1870,7 +1906,8 @@ " 'last_name', person_5.last_name,", " 'age', person_5.age,", " 'rating', person_5.rating,", - " 'tags', person_5.tags", + " 'tags', person_5.tags,", + " 'labels', person_5.labels", " )", " FROM agreego.entity entity_3", " JOIN agreego.organization organization_4", @@ -1982,7 +2019,8 @@ " 'last_name', person_10.last_name,", " 'age', person_10.age,", " 'rating', person_10.rating,", - " 'tags', person_10.tags", + " 'tags', person_10.tags,", + " 'labels', person_10.labels", " )", " FROM agreego.entity entity_8", " JOIN agreego.organization organization_9", @@ -2038,7 +2076,8 @@ " 'first_name', person_8.first_name,", " 'last_name', person_8.last_name,", " 'rating', person_8.rating,", - " 'tags', person_8.tags", + " 'tags', person_8.tags,", + " 'labels', person_8.labels", " )", " FROM agreego.entity entity_6", " JOIN agreego.organization organization_7", @@ -2080,6 +2119,7 @@ " 'age', person_5.age,", " 'rating', person_5.rating,", " 'tags', person_5.tags,", + " 'labels', person_5.labels,", " 'phone_numbers', (", " SELECT COALESCE(jsonb_agg(jsonb_build_object(", " 'id', entity_6.id,", @@ -2276,7 +2316,8 @@ " 'last_name', person_5.last_name,", " 'age', person_5.age,", " 'rating', person_5.rating,", - " 'tags', person_5.tags", + " 'tags', person_5.tags,", + " 'labels', person_5.labels", " )", " FROM agreego.entity entity_3", " JOIN agreego.organization organization_4", @@ -2461,7 +2502,8 @@ " 'last_name', person_12.last_name,", " 'age', person_12.age,", " 'rating', person_12.rating,", - " 'tags', person_12.tags", + " 'tags', person_12.tags,", + " 'labels', person_12.labels", " )", " FROM agreego.entity entity_10", " JOIN agreego.organization organization_11", @@ -2503,6 +2545,9 @@ "plumbing", "electrical" ] + }, + "labels": { + "$eq": "vip" } }, "expect": { @@ -2521,6 +2566,7 @@ " 'age', person_3.age,", " 'rating', person_3.rating,", " 'tags', person_3.tags,", + " 'labels', person_3.labels,", " 'phone_numbers', (", " SELECT COALESCE(jsonb_agg(jsonb_build_object(", " 'id', entity_4.id,", @@ -2677,10 +2723,11 @@ " JOIN agreego.person person_3", " WHERE", " NOT entity_1.archived", - " AND person_3.rating >= ($1 #>> '{}')::NUMERIC", - " AND person_3.tags ? ($2 #>> '{)", - " AND person_3.tags ?| ARRAY()", - " ))))" + " AND person_3.labels ? ($1 #>> '{)", + " AND person_3.rating >= ($2 #>> '{}')::NUMERIC", + " AND person_3.tags ? ($3 #>> '{)", + " AND person_3.tags ?| ARRAY()", + " ))))" ] ] } diff --git a/src/queryer/compiler.rs b/src/queryer/compiler.rs index 9c3e905..2330432 100644 --- a/src/queryer/compiler.rs +++ b/src/queryer/compiler.rs @@ -762,17 +762,20 @@ impl<'a> Compiler<'a> { .and_then(|v| v.as_str()) == Some("jsonb"); if is_jsonb { + // Compiled schemas normalize to the list form ("type": ["array"]), + // hand-written ones may use the single form — accept both let is_array_prop = node .schema .obj .properties .as_ref() .and_then(|p| p.get(field_name)) - .map(|ps| { - matches!( - &ps.obj.type_, - Some(crate::database::object::SchemaTypeOrArray::Single(t)) if t == "array" - ) + .map(|ps| match &ps.obj.type_ { + Some(crate::database::object::SchemaTypeOrArray::Single(t)) => t == "array", + Some(crate::database::object::SchemaTypeOrArray::Multiple(ts)) => { + ts.iter().any(|t| t == "array") && ts.iter().all(|t| t == "array" || t == "null") + } + None => false, }) .unwrap_or(false);