Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 569eb1d2ea | |||
| 6cebce3740 | |||
| d3de3961c1 | |||
| d0ae6eeddd |
@ -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 #>> '{)",
|
||||||
" ))))"
|
" ))))"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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"));
|
||||||
|
|||||||
Reference in New Issue
Block a user