merger now requires a schema id, queryer and merger now use pre-compiled edges for O(1) relations
This commit is contained in:
@ -12,6 +12,7 @@ pub struct Node<'a> {
|
||||
pub parent_alias: String,
|
||||
pub parent_type_aliases: Option<std::sync::Arc<std::collections::HashMap<String, String>>>,
|
||||
pub parent_type: Option<&'a crate::database::r#type::Type>,
|
||||
pub parent_schema: Option<std::sync::Arc<crate::database::schema::Schema>>,
|
||||
pub property_name: Option<String>,
|
||||
pub depth: usize,
|
||||
pub ast_path: String,
|
||||
@ -39,6 +40,7 @@ impl<'a> Compiler<'a> {
|
||||
parent_alias: "t1".to_string(),
|
||||
parent_type_aliases: None,
|
||||
parent_type: None,
|
||||
parent_schema: None,
|
||||
property_name: None,
|
||||
depth: 0,
|
||||
ast_path: String::new(),
|
||||
@ -243,6 +245,7 @@ impl<'a> Compiler<'a> {
|
||||
if fam_type_def.variations.len() == 1 {
|
||||
let mut bypass_schema = crate::database::schema::Schema::default();
|
||||
bypass_schema.obj.r#ref = Some(family_target.clone());
|
||||
bypass_schema.compile(self.db, &mut std::collections::HashSet::new());
|
||||
|
||||
let mut bypass_node = node.clone();
|
||||
bypass_node.schema = std::sync::Arc::new(bypass_schema);
|
||||
@ -258,6 +261,7 @@ impl<'a> Compiler<'a> {
|
||||
for variation in &sorted_fam_variations {
|
||||
let mut ref_schema = crate::database::schema::Schema::default();
|
||||
ref_schema.obj.r#ref = Some(variation.clone());
|
||||
ref_schema.compile(self.db, &mut std::collections::HashSet::new());
|
||||
family_schemas.push(std::sync::Arc::new(ref_schema));
|
||||
}
|
||||
|
||||
@ -395,9 +399,7 @@ impl<'a> Compiler<'a> {
|
||||
) -> Result<Vec<String>, String> {
|
||||
let mut select_args = Vec::new();
|
||||
let grouped_fields = r#type.grouped_fields.as_ref().and_then(|v| v.as_object());
|
||||
let merged_props = self
|
||||
.db
|
||||
.merged_properties(node.schema.as_ref(), &mut std::collections::HashSet::new());
|
||||
let merged_props = node.schema.obj.compiled_properties.get().unwrap();
|
||||
let mut sorted_keys: Vec<&String> = merged_props.keys().collect();
|
||||
sorted_keys.sort();
|
||||
|
||||
@ -451,6 +453,7 @@ impl<'a> Compiler<'a> {
|
||||
let arc_aliases = std::sync::Arc::new(table_aliases.clone());
|
||||
child_node.parent_type_aliases = Some(arc_aliases);
|
||||
child_node.parent_type = Some(r#type);
|
||||
child_node.parent_schema = Some(std::sync::Arc::clone(&node.schema));
|
||||
child_node.property_name = Some(prop_key.clone());
|
||||
child_node.depth += 1;
|
||||
let next_path = if node.ast_path.is_empty() {
|
||||
@ -663,60 +666,61 @@ impl<'a> Compiler<'a> {
|
||||
) -> Result<(), String> {
|
||||
if let Some(prop_ref) = &node.property_name {
|
||||
let prop = prop_ref.as_str();
|
||||
println!("DEBUG: Eval prop: {}", prop);
|
||||
|
||||
let mut parent_relation_alias = node.parent_alias.clone();
|
||||
let mut child_relation_alias = base_alias.to_string();
|
||||
|
||||
if let Some(parent_type) = node.parent_type {
|
||||
let merged_props = self
|
||||
.db
|
||||
.merged_properties(node.schema.as_ref(), &mut std::collections::HashSet::new());
|
||||
let relative_keys: Vec<String> = merged_props.keys().cloned().collect();
|
||||
if let Some(parent_schema) = &node.parent_schema {
|
||||
if let Some(compiled_edges) = parent_schema.obj.compiled_edges.get() {
|
||||
if let Some(edge) = compiled_edges.get(prop) {
|
||||
let is_parent_source = edge.forward;
|
||||
let relation = self.db.relations.get(&edge.constraint).ok_or_else(|| {
|
||||
format!(
|
||||
"Could not find exact relation constraint {} statically mapped from {} -> {} property {}",
|
||||
edge.constraint, parent_type.name, r#type.name, prop
|
||||
)
|
||||
})?;
|
||||
|
||||
let (relation, is_parent_source) = self
|
||||
.db
|
||||
.get_relation(&parent_type.name, &r#type.name, prop, Some(&relative_keys))
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"Could not dynamically resolve database relation mapping for {} -> {} on property {}",
|
||||
parent_type.name, r#type.name, prop
|
||||
)
|
||||
})?;
|
||||
let source_col = &relation.source_columns[0];
|
||||
let dest_col = &relation.destination_columns[0];
|
||||
|
||||
let source_col = &relation.source_columns[0];
|
||||
let dest_col = &relation.destination_columns[0];
|
||||
if let Some(pta) = &node.parent_type_aliases {
|
||||
let p_search_type = if is_parent_source {
|
||||
&relation.source_type
|
||||
} else {
|
||||
&relation.destination_type
|
||||
};
|
||||
if let Some(a) = pta.get(p_search_type) {
|
||||
parent_relation_alias = a.clone();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pta) = &node.parent_type_aliases {
|
||||
let p_search_type = if is_parent_source {
|
||||
&relation.source_type
|
||||
} else {
|
||||
&relation.destination_type
|
||||
};
|
||||
if let Some(a) = pta.get(p_search_type) {
|
||||
parent_relation_alias = a.clone();
|
||||
let c_search_type = if is_parent_source {
|
||||
&relation.destination_type
|
||||
} else {
|
||||
&relation.source_type
|
||||
};
|
||||
if let Some(a) = type_aliases.get(c_search_type) {
|
||||
child_relation_alias = a.clone();
|
||||
}
|
||||
|
||||
let sql_string = if is_parent_source {
|
||||
format!(
|
||||
"{}.{} = {}.{}",
|
||||
parent_relation_alias, source_col, child_relation_alias, dest_col
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}.{} = {}.{}",
|
||||
child_relation_alias, source_col, parent_relation_alias, dest_col
|
||||
)
|
||||
};
|
||||
where_clauses.push(sql_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let c_search_type = if is_parent_source {
|
||||
&relation.destination_type
|
||||
} else {
|
||||
&relation.source_type
|
||||
};
|
||||
if let Some(a) = type_aliases.get(c_search_type) {
|
||||
child_relation_alias = a.clone();
|
||||
}
|
||||
|
||||
let sql_string = if is_parent_source {
|
||||
format!(
|
||||
"{}.{} = {}.{}",
|
||||
parent_relation_alias, source_col, child_relation_alias, dest_col
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}.{} = {}.{}",
|
||||
child_relation_alias, source_col, parent_relation_alias, dest_col
|
||||
)
|
||||
};
|
||||
where_clauses.push(sql_string);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user