queryer: typed filter conditions for float and jsonb columns — (a) float4/float8 (the pg typnames that actually arrive in field_types; 'real'/'double precision' never do) now cast the parameter ::numeric, fixing 'double precision >= text' on $gt/$gte/etc; (b) jsonb columns compile explicitly: array-valued properties (tag lists) get CONTAINMENT semantics ($eq→?, $ne→NOT ?, $of→?|, $nof→NOT ?|), non-array jsonb compares ::jsonb for $eq/$ne, and unsupported operators are a loud QUERY_COMPILATION_FAILED naming the property instead of a runtime SQL type error ('jsonb = text'). compile_filter_conditions now returns Result. New fixture case (float8 $gte + jsonb array $eq/$of); 1279 tests green. Unblocks agreego TestListVendors_FilterByTrade/FilterByRating.
This commit is contained in:
@ -365,7 +365,9 @@
|
||||
"name",
|
||||
"age",
|
||||
"archived",
|
||||
"created_at"
|
||||
"created_at",
|
||||
"rating",
|
||||
"tags"
|
||||
],
|
||||
"grouped_fields": {
|
||||
"entity": [
|
||||
@ -380,7 +382,9 @@
|
||||
"person": [
|
||||
"first_name",
|
||||
"last_name",
|
||||
"age"
|
||||
"age",
|
||||
"rating",
|
||||
"tags"
|
||||
]
|
||||
},
|
||||
"field_types": {
|
||||
@ -391,7 +395,9 @@
|
||||
"last_name": "text",
|
||||
"name": "text",
|
||||
"age": "numeric",
|
||||
"created_at": "timestamptz"
|
||||
"created_at": "timestamptz",
|
||||
"rating": "float8",
|
||||
"tags": "jsonb"
|
||||
},
|
||||
"schemas": {
|
||||
"person": {
|
||||
@ -405,6 +411,15 @@
|
||||
},
|
||||
"age": {
|
||||
"type": "number"
|
||||
},
|
||||
"rating": {
|
||||
"type": "number"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -416,6 +431,15 @@
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"rating": {
|
||||
"type": "number"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -475,6 +499,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"rating": {
|
||||
"type": "number"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1290,7 +1323,9 @@
|
||||
" 'name', organization_2.name,",
|
||||
" 'first_name', person_3.first_name,",
|
||||
" 'last_name', person_3.last_name,",
|
||||
" 'age', person_3.age",
|
||||
" 'age', person_3.age,",
|
||||
" 'rating', person_3.rating,",
|
||||
" 'tags', person_3.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_1",
|
||||
" JOIN agreego.organization organization_2",
|
||||
@ -1320,6 +1355,8 @@
|
||||
" 'first_name', person_3.first_name,",
|
||||
" 'last_name', person_3.last_name,",
|
||||
" 'age', person_3.age,",
|
||||
" 'rating', person_3.rating,",
|
||||
" 'tags', person_3.tags,",
|
||||
" 'phone_numbers', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_4.id,",
|
||||
@ -1570,6 +1607,8 @@
|
||||
" 'first_name', person_3.first_name,",
|
||||
" 'last_name', person_3.last_name,",
|
||||
" 'age', person_3.age,",
|
||||
" 'rating', person_3.rating,",
|
||||
" 'tags', person_3.tags,",
|
||||
" 'phone_numbers', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_4.id,",
|
||||
@ -1829,7 +1868,9 @@
|
||||
" 'name', organization_4.name,",
|
||||
" 'first_name', person_5.first_name,",
|
||||
" 'last_name', person_5.last_name,",
|
||||
" 'age', person_5.age",
|
||||
" 'age', person_5.age,",
|
||||
" 'rating', person_5.rating,",
|
||||
" 'tags', person_5.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_3",
|
||||
" JOIN agreego.organization organization_4",
|
||||
@ -1939,7 +1980,9 @@
|
||||
" 'name', organization_9.name,",
|
||||
" 'first_name', person_10.first_name,",
|
||||
" 'last_name', person_10.last_name,",
|
||||
" 'age', person_10.age",
|
||||
" 'age', person_10.age,",
|
||||
" 'rating', person_10.rating,",
|
||||
" 'tags', person_10.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_8",
|
||||
" JOIN agreego.organization organization_9",
|
||||
@ -1993,7 +2036,9 @@
|
||||
" 'created_at', entity_6.created_at,",
|
||||
" 'name', organization_7.name,",
|
||||
" 'first_name', person_8.first_name,",
|
||||
" 'last_name', person_8.last_name",
|
||||
" 'last_name', person_8.last_name,",
|
||||
" 'rating', person_8.rating,",
|
||||
" 'tags', person_8.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_6",
|
||||
" JOIN agreego.organization organization_7",
|
||||
@ -2033,6 +2078,8 @@
|
||||
" 'first_name', person_5.first_name,",
|
||||
" 'last_name', person_5.last_name,",
|
||||
" 'age', person_5.age,",
|
||||
" 'rating', person_5.rating,",
|
||||
" 'tags', person_5.tags,",
|
||||
" 'phone_numbers', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_6.id,",
|
||||
@ -2227,7 +2274,9 @@
|
||||
" 'name', organization_4.name,",
|
||||
" 'first_name', person_5.first_name,",
|
||||
" 'last_name', person_5.last_name,",
|
||||
" 'age', person_5.age",
|
||||
" 'age', person_5.age,",
|
||||
" 'rating', person_5.rating,",
|
||||
" 'tags', person_5.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_3",
|
||||
" JOIN agreego.organization organization_4",
|
||||
@ -2410,7 +2459,9 @@
|
||||
" 'name', organization_11.name,",
|
||||
" 'first_name', person_12.first_name,",
|
||||
" 'last_name', person_12.last_name,",
|
||||
" 'age', person_12.age",
|
||||
" 'age', person_12.age,",
|
||||
" 'rating', person_12.rating,",
|
||||
" 'tags', person_12.tags",
|
||||
" )",
|
||||
" FROM agreego.entity entity_10",
|
||||
" JOIN agreego.organization organization_11",
|
||||
@ -2437,6 +2488,202 @@
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Person filters: float8 comparison and jsonb array containment",
|
||||
"action": "query",
|
||||
"schema_id": "full.person",
|
||||
"filter": {
|
||||
"rating": {
|
||||
"$gte": 4.0
|
||||
},
|
||||
"tags": {
|
||||
"$eq": "landscaping",
|
||||
"$of": [
|
||||
"plumbing",
|
||||
"electrical"
|
||||
]
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"success": true,
|
||||
"sql": [
|
||||
[
|
||||
"((SELECT jsonb_strip_nulls((",
|
||||
" SELECT 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,",
|
||||
" 'phone_numbers', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_4.id,",
|
||||
" 'type', entity_4.type,",
|
||||
" 'archived', entity_4.archived,",
|
||||
" 'created_at', entity_4.created_at,",
|
||||
" 'is_primary', contact_6.is_primary,",
|
||||
" 'target', (",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_7.id,",
|
||||
" 'type', entity_7.type,",
|
||||
" 'archived', entity_7.archived,",
|
||||
" 'created_at', entity_7.created_at,",
|
||||
" 'number', phone_number_8.number",
|
||||
" )",
|
||||
" FROM agreego.entity entity_7",
|
||||
" JOIN agreego.phone_number phone_number_8",
|
||||
" WHERE",
|
||||
" NOT entity_7.archived",
|
||||
" AND relationship_5.target_id = entity_7.id",
|
||||
" )",
|
||||
" )), '[]'::jsonb)",
|
||||
" FROM agreego.entity entity_4",
|
||||
" JOIN agreego.relationship relationship_5",
|
||||
" JOIN agreego.contact contact_6",
|
||||
" WHERE",
|
||||
" NOT entity_4.archived",
|
||||
" AND relationship_5.target_type = 'phone_number'",
|
||||
" AND relationship_5.source_id = entity_1.id",
|
||||
" ),",
|
||||
" 'email_addresses', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_9.id,",
|
||||
" 'type', entity_9.type,",
|
||||
" 'archived', entity_9.archived,",
|
||||
" 'created_at', entity_9.created_at,",
|
||||
" 'is_primary', contact_11.is_primary,",
|
||||
" 'target', (",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_12.id,",
|
||||
" 'type', entity_12.type,",
|
||||
" 'archived', entity_12.archived,",
|
||||
" 'created_at', entity_12.created_at,",
|
||||
" 'address', email_address_13.address",
|
||||
" )",
|
||||
" FROM agreego.entity entity_12",
|
||||
" JOIN agreego.email_address email_address_13",
|
||||
" WHERE",
|
||||
" NOT entity_12.archived",
|
||||
" AND relationship_10.target_id = entity_12.id",
|
||||
" )",
|
||||
" )), '[]'::jsonb)",
|
||||
" FROM agreego.entity entity_9",
|
||||
" JOIN agreego.relationship relationship_10",
|
||||
" JOIN agreego.contact contact_11",
|
||||
" WHERE",
|
||||
" NOT entity_9.archived",
|
||||
" AND relationship_10.target_type = 'email_address'",
|
||||
" AND relationship_10.source_id = entity_1.id",
|
||||
" ),",
|
||||
" 'addresses', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_14.id,",
|
||||
" 'type', entity_14.type,",
|
||||
" 'archived', entity_14.archived,",
|
||||
" 'created_at', entity_14.created_at,",
|
||||
" 'is_primary', contact_16.is_primary,",
|
||||
" 'target', (",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_17.id,",
|
||||
" 'type', entity_17.type,",
|
||||
" 'archived', entity_17.archived,",
|
||||
" 'created_at', entity_17.created_at,",
|
||||
" 'city', address_18.city",
|
||||
" )",
|
||||
" FROM agreego.entity entity_17",
|
||||
" JOIN agreego.address address_18",
|
||||
" WHERE",
|
||||
" NOT entity_17.archived",
|
||||
" AND relationship_15.target_id = entity_17.id",
|
||||
" )",
|
||||
" )), '[]'::jsonb)",
|
||||
" FROM agreego.entity entity_14",
|
||||
" JOIN agreego.relationship relationship_15",
|
||||
" JOIN agreego.contact contact_16",
|
||||
" WHERE",
|
||||
" NOT entity_14.archived",
|
||||
" AND relationship_15.target_type = 'address'",
|
||||
" AND relationship_15.source_id = entity_1.id",
|
||||
" ),",
|
||||
" 'contacts', (",
|
||||
" SELECT COALESCE(jsonb_agg(jsonb_build_object(",
|
||||
" 'id', entity_19.id,",
|
||||
" 'type', entity_19.type,",
|
||||
" 'archived', entity_19.archived,",
|
||||
" 'created_at', entity_19.created_at,",
|
||||
" 'is_primary', contact_21.is_primary,",
|
||||
" 'target', CASE",
|
||||
" WHEN relationship_20.target_type = 'phone_number' THEN ((",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_22.id,",
|
||||
" 'type', entity_22.type,",
|
||||
" 'archived', entity_22.archived,",
|
||||
" 'created_at', entity_22.created_at,",
|
||||
" 'number', phone_number_23.number",
|
||||
" )",
|
||||
" FROM agreego.entity entity_22",
|
||||
" JOIN agreego.phone_number phone_number_23",
|
||||
" WHERE",
|
||||
" NOT entity_22.archived",
|
||||
" AND relationship_20.target_id = entity_22.id",
|
||||
" ))",
|
||||
" WHEN relationship_20.target_type = 'email_address' THEN ((",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_24.id,",
|
||||
" 'type', entity_24.type,",
|
||||
" 'archived', entity_24.archived,",
|
||||
" 'created_at', entity_24.created_at,",
|
||||
" 'address', email_address_25.address",
|
||||
" )",
|
||||
" FROM agreego.entity entity_24",
|
||||
" JOIN agreego.email_address email_address_25",
|
||||
" WHERE",
|
||||
" NOT entity_24.archived",
|
||||
" AND relationship_20.target_id = entity_24.id",
|
||||
" ))",
|
||||
" WHEN relationship_20.target_type = 'address' THEN ((",
|
||||
" SELECT jsonb_build_object(",
|
||||
" 'id', entity_26.id,",
|
||||
" 'type', entity_26.type,",
|
||||
" 'archived', entity_26.archived,",
|
||||
" 'created_at', entity_26.created_at,",
|
||||
" 'city', address_27.city",
|
||||
" )",
|
||||
" FROM agreego.entity entity_26",
|
||||
" JOIN agreego.address address_27",
|
||||
" WHERE",
|
||||
" NOT entity_26.archived",
|
||||
" AND relationship_20.target_id = entity_26.id",
|
||||
" ))",
|
||||
" ELSE NULL",
|
||||
" END",
|
||||
" )), '[]'::jsonb)",
|
||||
" FROM agreego.entity entity_19",
|
||||
" JOIN agreego.relationship relationship_20",
|
||||
" JOIN agreego.contact contact_21",
|
||||
" WHERE",
|
||||
" NOT entity_19.archived",
|
||||
" AND relationship_20.source_id = entity_1.id",
|
||||
" )",
|
||||
" )",
|
||||
" FROM agreego.entity entity_1",
|
||||
" JOIN agreego.organization organization_2",
|
||||
" 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()",
|
||||
" ))))"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user