Compare commits

...

2 Commits

Author SHA1 Message Date
9fe5a34163 version: 1.0.91 2026-03-25 21:37:15 -04:00
f5bf21eb58 fixed root array queries 2026-03-25 21:37:01 -04:00
4 changed files with 86 additions and 20 deletions

View File

@ -20,6 +20,16 @@
"$family": "base.person" "$family": "base.person"
} }
] ]
},
{
"name": "get_orders",
"schemas": [
{
"$id": "get_orders.response",
"type": "array",
"items": { "$ref": "light.order" }
}
]
} }
], ],
"enums": [], "enums": [],
@ -664,6 +674,15 @@
} }
} }
}, },
{
"$id": "light.order",
"$ref": "order",
"properties": {
"customer": {
"$ref": "base.person"
}
}
},
{ {
"$id": "full.order", "$id": "full.order",
"$ref": "order", "$ref": "order",
@ -1569,6 +1588,47 @@
] ]
] ]
} }
},
{
"description": "Root Array SQL evaluation for Order fetching Light Order",
"action": "query",
"schema_id": "get_orders.response",
"expect": {
"success": true,
"sql": [
[
"(SELECT COALESCE(jsonb_agg(jsonb_build_object(",
" 'archived', entity_2.archived,",
" 'created_at', entity_2.created_at,",
" 'customer',",
" (SELECT jsonb_build_object(",
" 'age', person_3.age,",
" 'archived', entity_5.archived,",
" 'created_at', entity_5.created_at,",
" 'first_name', person_3.first_name,",
" 'id', entity_5.id,",
" 'last_name', person_3.last_name,",
" 'name', entity_5.name,",
" 'type', entity_5.type",
" )",
" FROM agreego.person person_3",
" JOIN agreego.organization organization_4 ON organization_4.id = person_3.id",
" JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id",
" WHERE",
" NOT entity_5.archived",
" AND order_1.customer_id = person_3.id),",
" 'customer_id', order_1.customer_id,",
" 'id', entity_2.id,",
" 'name', entity_2.name,",
" 'total', order_1.total,",
" 'type', entity_2.type",
")), '[]'::jsonb)",
"FROM agreego.order order_1",
"JOIN agreego.entity entity_2 ON entity_2.id = order_1.id",
"WHERE NOT entity_2.archived)"
]
]
}
} }
] ]
} }

View File

@ -63,33 +63,33 @@ impl<'a> Compiler<'a> {
} }
fn compile_array(&mut self, node: Node<'a>) -> Result<(String, String), String> { fn compile_array(&mut self, node: Node<'a>) -> Result<(String, String), String> {
// 1. Array of DB Entities (`$ref` or `$family` pointing to a table limit)
if let Some(items) = &node.schema.obj.items { if let Some(items) = &node.schema.obj.items {
let next_path = node.ast_path.clone(); let mut resolved_type = None;
if let Some(family_target) = items.obj.family.as_ref() {
if let Some(ref_id) = &items.obj.r#ref { let base_type_name = family_target.split('.').next_back().unwrap_or(family_target);
if let Some(type_def) = self.db.types.get(ref_id) { resolved_type = self.db.types.get(base_type_name);
let mut entity_node = node.clone(); } else if let Some(base_type_name) = items.obj.identifier() {
entity_node.ast_path = next_path; resolved_type = self.db.types.get(&base_type_name);
entity_node.schema = std::sync::Arc::clone(items);
return self.compile_entity(type_def, entity_node, true);
}
} }
let mut next_node = node.clone(); if let Some(type_def) = resolved_type {
next_node.depth += 1; let mut entity_node = node.clone();
next_node.ast_path = next_path; entity_node.schema = std::sync::Arc::clone(items);
next_node.schema = std::sync::Arc::clone(items); return self.compile_entity(type_def, entity_node, true);
let (item_sql, _) = self.compile_node(next_node)?; }
}
// 2. Arrays of mapped Native Postgres Columns (e.g. `jsonb`, `text[]`)
if let Some(prop) = &node.property_name {
return Ok(( return Ok((
format!("(SELECT jsonb_agg({}) FROM TODO)", item_sql), format!("{}.{}", node.parent_alias, prop),
"array".to_string(), "array".to_string(),
)); ));
} }
Ok(( // 3. Fallback for root execution of standalone non-entity arrays
"SELECT jsonb_agg(TODO) FROM TODO".to_string(), Err("Cannot compile a root array without a valid entity reference or table mapped via `items`.".to_string())
"array".to_string(),
))
} }
fn compile_reference(&mut self, node: Node<'a>) -> Result<(String, String), String> { fn compile_reference(&mut self, node: Node<'a>) -> Result<(String, String), String> {

View File

@ -1457,6 +1457,12 @@ fn test_queryer_0_7() {
crate::tests::runner::run_test_case(&path, 0, 7).unwrap(); crate::tests::runner::run_test_case(&path, 0, 7).unwrap();
} }
#[test]
fn test_queryer_0_8() {
let path = format!("{}/fixtures/queryer.json", env!("CARGO_MANIFEST_DIR"));
crate::tests::runner::run_test_case(&path, 0, 8).unwrap();
}
#[test] #[test]
fn test_not_0_0() { fn test_not_0_0() {
let path = format!("{}/fixtures/not.json", env!("CARGO_MANIFEST_DIR")); let path = format!("{}/fixtures/not.json", env!("CARGO_MANIFEST_DIR"));

View File

@ -1 +1 @@
1.0.90 1.0.91