re-applied fix for family in conditions
This commit is contained in:
@ -295,6 +295,7 @@ The Queryer transforms Postgres into a pre-compiled Semantic Query Engine, desig
|
|||||||
* **The Dot Convention**: When a schema requests `family: "target.schema"`, the compiler extracts the base type (e.g. `schema`) and looks up its Physical Table definition.
|
* **The Dot Convention**: When a schema requests `family: "target.schema"`, the compiler extracts the base type (e.g. `schema`) and looks up its Physical Table definition.
|
||||||
* **Multi-Table Branching**: If the Physical Table is a parent to other tables (e.g. `organization` has variations `["organization", "bot", "person"]`), the compiler generates a dynamic `CASE WHEN type = '...' THEN ...` query, expanding into sub-queries for each variation. To ensure safe resolution, the compiler dynamically evaluates correlation boundaries: it attempts standard Relational Edge discovery first. If no explicit relational edge exists (indicating pure Table Inheritance rather than a standard foreign-key graph relationship), it safely invokes a **Table Parity Fallback**. This generates an explicit ID correlation constraint (`AND inner.id = outer.id`), perfectly binding the structural variations back to the parent row to eliminate Cartesian products.
|
* **Multi-Table Branching**: If the Physical Table is a parent to other tables (e.g. `organization` has variations `["organization", "bot", "person"]`), the compiler generates a dynamic `CASE WHEN type = '...' THEN ...` query, expanding into sub-queries for each variation. To ensure safe resolution, the compiler dynamically evaluates correlation boundaries: it attempts standard Relational Edge discovery first. If no explicit relational edge exists (indicating pure Table Inheritance rather than a standard foreign-key graph relationship), it safely invokes a **Table Parity Fallback**. This generates an explicit ID correlation constraint (`AND inner.id = outer.id`), perfectly binding the structural variations back to the parent row to eliminate Cartesian products.
|
||||||
* **Single-Table Bypass**: If the Physical Table is a leaf node with only one variation (e.g. `person` has variations `["person"]`), the compiler cleanly bypasses `CASE` generation and compiles a simple `SELECT` across the base table, as all schema extensions (e.g. `light.person`, `full.person`) are guaranteed to reside in the exact same physical row.
|
* **Single-Table Bypass**: If the Physical Table is a leaf node with only one variation (e.g. `person` has variations `["person"]`), the compiler cleanly bypasses `CASE` generation and compiles a simple `SELECT` across the base table, as all schema extensions (e.g. `light.person`, `full.person`) are guaranteed to reside in the exact same physical row.
|
||||||
|
* **Polymorphic Relation Type Filtering**: When a relationship maps to a polymorphic target with variations, the Queryer compiles an `IN` clause containing all allowed table variations (e.g., `counterparty_type IN ('bot', 'organization', 'person')`) rather than matching the base type literal, ensuring all polymorphic types are loaded correctly.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -2432,7 +2432,7 @@
|
|||||||
" JOIN agreego.entity entity_2 ON entity_2.id = order_1.id",
|
" JOIN agreego.entity entity_2 ON entity_2.id = order_1.id",
|
||||||
" WHERE",
|
" WHERE",
|
||||||
" NOT entity_2.archived",
|
" NOT entity_2.archived",
|
||||||
" AND order_1.counterparty_type = 'organization'",
|
" AND order_1.counterparty_type IN ('bot', 'organization', 'person')",
|
||||||
"))))"
|
"))))"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|||||||
@ -603,7 +603,7 @@ impl<'a> Compiler<'a> {
|
|||||||
|
|
||||||
if let Some(type_name) = bound_type_name {
|
if let Some(type_name) = bound_type_name {
|
||||||
// Ensure this type actually exists
|
// Ensure this type actually exists
|
||||||
if self.db.types.contains_key(&type_name) {
|
if let Some(type_def) = self.db.types.get(&type_name) {
|
||||||
if let Some(relation) = self.db.relations.get(&edge.constraint) {
|
if let Some(relation) = self.db.relations.get(&edge.constraint) {
|
||||||
let mut poly_col = None;
|
let mut poly_col = None;
|
||||||
let mut table_to_alias = "";
|
let mut table_to_alias = "";
|
||||||
@ -621,6 +621,19 @@ impl<'a> Compiler<'a> {
|
|||||||
.get(table_to_alias)
|
.get(table_to_alias)
|
||||||
.or_else(|| type_aliases.get(&node.parent_alias))
|
.or_else(|| type_aliases.get(&node.parent_alias))
|
||||||
{
|
{
|
||||||
|
if type_def.variations.len() > 1 {
|
||||||
|
let quoted: Vec<String> = type_def
|
||||||
|
.variations
|
||||||
|
.iter()
|
||||||
|
.map(|v| format!("'{}'", v))
|
||||||
|
.collect();
|
||||||
|
where_clauses.push(format!(
|
||||||
|
"{}.{} IN ({})",
|
||||||
|
alias,
|
||||||
|
col,
|
||||||
|
quoted.join(", ")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
where_clauses.push(format!("{}.{} = '{}'", alias, col, type_name));
|
where_clauses.push(format!("{}.{} = '{}'", alias, col, type_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,6 +645,7 @@ impl<'a> Compiler<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_filter_alias(
|
fn resolve_filter_alias(
|
||||||
r#type: &crate::database::r#type::Type,
|
r#type: &crate::database::r#type::Type,
|
||||||
|
|||||||
13
traits_debug_val.json
Normal file
13
traits_debug_val.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"name": "uniqueItems_6_0",
|
||||||
|
"schemas": {
|
||||||
|
"uniqueItems_6_0": {
|
||||||
|
"uniqueItems": true,
|
||||||
|
"extensible": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user