Compare commits

...

4 Commits

4 changed files with 147 additions and 19 deletions

View File

@ -70,6 +70,17 @@
} }
} }
} }
},
{
"name": "get_people",
"schemas": {
"get_people.response": {
"type": "array",
"items": {
"type": "person"
}
}
}
} }
], ],
"enums": [], "enums": [],
@ -367,7 +378,8 @@
"archived", "archived",
"created_at", "created_at",
"rating", "rating",
"tags" "tags",
"labels"
], ],
"grouped_fields": { "grouped_fields": {
"entity": [ "entity": [
@ -384,7 +396,8 @@
"last_name", "last_name",
"age", "age",
"rating", "rating",
"tags" "tags",
"labels"
] ]
}, },
"field_types": { "field_types": {
@ -397,7 +410,8 @@
"age": "numeric", "age": "numeric",
"created_at": "timestamptz", "created_at": "timestamptz",
"rating": "float8", "rating": "float8",
"tags": "jsonb" "tags": "jsonb",
"labels": "jsonb"
}, },
"schemas": { "schemas": {
"person": { "person": {
@ -420,6 +434,16 @@
"items": { "items": {
"type": "string" "type": "string"
} }
},
"labels": {
"type": [
"array"
],
"items": {
"type": [
"string"
]
}
} }
} }
}, },
@ -440,6 +464,16 @@
"items": { "items": {
"type": "string" "type": "string"
} }
},
"labels": {
"type": [
"array"
],
"items": {
"type": [
"string"
]
}
} }
} }
}, },
@ -508,6 +542,16 @@
"items": { "items": {
"type": "string" "type": "string"
} }
},
"labels": {
"type": [
"array"
],
"items": {
"type": [
"string"
]
}
} }
} }
} }
@ -1325,7 +1369,8 @@
" 'last_name', person_3.last_name,", " 'last_name', person_3.last_name,",
" 'age', person_3.age,", " 'age', person_3.age,",
" 'rating', person_3.rating,", " 'rating', person_3.rating,",
" 'tags', person_3.tags", " 'tags', person_3.tags,",
" 'labels', person_3.labels",
" )", " )",
" FROM agreego.entity entity_1", " FROM agreego.entity entity_1",
" JOIN agreego.organization organization_2", " JOIN agreego.organization organization_2",
@ -1357,6 +1402,7 @@
" 'age', person_3.age,", " 'age', person_3.age,",
" 'rating', person_3.rating,", " 'rating', person_3.rating,",
" 'tags', person_3.tags,", " 'tags', person_3.tags,",
" 'labels', person_3.labels,",
" 'phone_numbers', (", " 'phone_numbers', (",
" SELECT COALESCE(jsonb_agg(jsonb_build_object(", " SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'id', entity_4.id,", " 'id', entity_4.id,",
@ -1609,6 +1655,7 @@
" 'age', person_3.age,", " 'age', person_3.age,",
" 'rating', person_3.rating,", " 'rating', person_3.rating,",
" 'tags', person_3.tags,", " 'tags', person_3.tags,",
" 'labels', person_3.labels,",
" 'phone_numbers', (", " 'phone_numbers', (",
" SELECT COALESCE(jsonb_agg(jsonb_build_object(", " SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'id', entity_4.id,", " 'id', entity_4.id,",
@ -1870,7 +1917,8 @@
" 'last_name', person_5.last_name,", " 'last_name', person_5.last_name,",
" 'age', person_5.age,", " 'age', person_5.age,",
" 'rating', person_5.rating,", " 'rating', person_5.rating,",
" 'tags', person_5.tags", " 'tags', person_5.tags,",
" 'labels', person_5.labels",
" )", " )",
" FROM agreego.entity entity_3", " FROM agreego.entity entity_3",
" JOIN agreego.organization organization_4", " JOIN agreego.organization organization_4",
@ -1982,7 +2030,8 @@
" 'last_name', person_10.last_name,", " 'last_name', person_10.last_name,",
" 'age', person_10.age,", " 'age', person_10.age,",
" 'rating', person_10.rating,", " 'rating', person_10.rating,",
" 'tags', person_10.tags", " 'tags', person_10.tags,",
" 'labels', person_10.labels",
" )", " )",
" FROM agreego.entity entity_8", " FROM agreego.entity entity_8",
" JOIN agreego.organization organization_9", " JOIN agreego.organization organization_9",
@ -2038,7 +2087,8 @@
" 'first_name', person_8.first_name,", " 'first_name', person_8.first_name,",
" 'last_name', person_8.last_name,", " 'last_name', person_8.last_name,",
" 'rating', person_8.rating,", " 'rating', person_8.rating,",
" 'tags', person_8.tags", " 'tags', person_8.tags,",
" 'labels', person_8.labels",
" )", " )",
" FROM agreego.entity entity_6", " FROM agreego.entity entity_6",
" JOIN agreego.organization organization_7", " JOIN agreego.organization organization_7",
@ -2080,6 +2130,7 @@
" 'age', person_5.age,", " 'age', person_5.age,",
" 'rating', person_5.rating,", " 'rating', person_5.rating,",
" 'tags', person_5.tags,", " 'tags', person_5.tags,",
" 'labels', person_5.labels,",
" 'phone_numbers', (", " 'phone_numbers', (",
" SELECT COALESCE(jsonb_agg(jsonb_build_object(", " SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'id', entity_6.id,", " 'id', entity_6.id,",
@ -2276,7 +2327,8 @@
" 'last_name', person_5.last_name,", " 'last_name', person_5.last_name,",
" 'age', person_5.age,", " 'age', person_5.age,",
" 'rating', person_5.rating,", " 'rating', person_5.rating,",
" 'tags', person_5.tags", " 'tags', person_5.tags,",
" 'labels', person_5.labels",
" )", " )",
" FROM agreego.entity entity_3", " FROM agreego.entity entity_3",
" JOIN agreego.organization organization_4", " JOIN agreego.organization organization_4",
@ -2461,7 +2513,8 @@
" 'last_name', person_12.last_name,", " 'last_name', person_12.last_name,",
" 'age', person_12.age,", " 'age', person_12.age,",
" 'rating', person_12.rating,", " 'rating', person_12.rating,",
" 'tags', person_12.tags", " 'tags', person_12.tags,",
" 'labels', person_12.labels",
" )", " )",
" FROM agreego.entity entity_10", " FROM agreego.entity entity_10",
" JOIN agreego.organization organization_11", " JOIN agreego.organization organization_11",
@ -2503,6 +2556,9 @@
"plumbing", "plumbing",
"electrical" "electrical"
] ]
},
"labels": {
"$eq": "vip"
} }
}, },
"expect": { "expect": {
@ -2521,6 +2577,7 @@
" 'age', person_3.age,", " 'age', person_3.age,",
" 'rating', person_3.rating,", " 'rating', person_3.rating,",
" 'tags', person_3.tags,", " 'tags', person_3.tags,",
" 'labels', person_3.labels,",
" 'phone_numbers', (", " 'phone_numbers', (",
" SELECT COALESCE(jsonb_agg(jsonb_build_object(", " SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'id', entity_4.id,", " 'id', entity_4.id,",
@ -2677,9 +2734,59 @@
" JOIN agreego.person person_3", " JOIN agreego.person person_3",
" WHERE", " WHERE",
" NOT entity_1.archived", " NOT entity_1.archived",
" AND person_3.rating >= ($1 #>> '{}')::NUMERIC", " AND person_3.labels ? ($1 #>> '{)",
" AND person_3.tags ? ($2 #>> '{)", " AND person_3.rating >= ($2 #>> '{}')::NUMERIC",
" AND person_3.tags ?| ARRAY()", " AND person_3.tags ? ($3 #>> '{)",
" AND person_3.tags ?| ARRAY()",
" ))))"
]
]
}
},
{
"description": "Punc response items proxy: jsonb array containment filter falls back to the type schema",
"action": "query",
"schema_id": "get_people.response",
"filter": {
"tags": {
"$eq": "landscaping"
},
"labels": {
"$of": [
"vip",
"board"
]
},
"rating": {
"$gte": 4.0
}
},
"expect": {
"success": true,
"sql": [
[
"((SELECT jsonb_strip_nulls((",
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'id', entity_1.id,",
" 'type', entity_1.type,",
" 'archived', entity_1.archived,",
" 'created_at', entity_1.created_at,",
" 'name', organization_2.name,",
" 'first_name', person_3.first_name,",
" 'last_name', person_3.last_name,",
" 'age', person_3.age,",
" 'rating', person_3.rating,",
" 'tags', person_3.tags,",
" 'labels', person_3.labels",
" )), '[]'::jsonb)",
" FROM agreego.entity entity_1",
" JOIN agreego.organization organization_2",
" JOIN agreego.person person_3",
" WHERE",
" NOT entity_1.archived",
" AND person_3.labels ?| ARRAY()",
" AND person_3.rating >= ($2 #>> '{}')::NUMERIC",
" AND person_3.tags ? ($3 #>> '{)",
" ))))" " ))))"
] ]
] ]

View File

@ -762,17 +762,32 @@ impl<'a> Compiler<'a> {
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
== Some("jsonb"); == Some("jsonb");
if is_jsonb { if is_jsonb {
let is_array_prop = node // The node schema may be a punc-response proxy without properties —
// fall back to the type's own schema. Compiled schemas normalize to
// the list form ("type": ["array"]), hand-written ones may use the
// single form — accept both.
let prop_schema = node
.schema .schema
.obj .obj
.properties .properties
.as_ref() .as_ref()
.and_then(|p| p.get(field_name)) .and_then(|p| p.get(field_name))
.map(|ps| { .cloned()
matches!( .or_else(|| {
&ps.obj.type_, r#type
Some(crate::database::object::SchemaTypeOrArray::Single(t)) if t == "array" .schemas
) .get(&r#type.name)
.and_then(|s| s.obj.properties.as_ref())
.and_then(|p| p.get(field_name))
.cloned()
});
let is_array_prop = prop_schema
.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); .unwrap_or(false);

View File

@ -1307,6 +1307,12 @@ fn test_queryer_0_16() {
crate::tests::runner::run_test_case(&path, 0, 16).unwrap(); crate::tests::runner::run_test_case(&path, 0, 16).unwrap();
} }
#[test]
fn test_queryer_0_17() {
let path = format!("{}/fixtures/queryer.json", env!("CARGO_MANIFEST_DIR"));
crate::tests::runner::run_test_case(&path, 0, 17).unwrap();
}
#[test] #[test]
fn test_polymorphism_0_0() { fn test_polymorphism_0_0() {
let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR")); let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR"));

View File

@ -1 +1 @@
1.0.173 1.0.175