progress
This commit is contained in:
@ -124,33 +124,28 @@ impl<'a> Compiler<'a> {
|
||||
}
|
||||
// Handle $family Polymorphism fallbacks for relations
|
||||
if let Some(family_target) = &node.schema.obj.family {
|
||||
let base_type_name = family_target
|
||||
.split('.')
|
||||
.next_back()
|
||||
.unwrap_or(family_target)
|
||||
.to_string();
|
||||
|
||||
if let Some(type_def) = self.db.types.get(&base_type_name) {
|
||||
if type_def.variations.len() == 1 {
|
||||
let mut bypass_schema = crate::database::schema::Schema::default();
|
||||
bypass_schema.obj.r#ref = Some(family_target.clone());
|
||||
let mut bypass_node = node.clone();
|
||||
bypass_node.schema = std::sync::Arc::new(bypass_schema);
|
||||
return self.compile_node(bypass_node);
|
||||
}
|
||||
|
||||
let mut sorted_variations: Vec<String> = type_def.variations.iter().cloned().collect();
|
||||
sorted_variations.sort();
|
||||
|
||||
let mut family_schemas = Vec::new();
|
||||
for variation in &sorted_variations {
|
||||
let mut ref_schema = crate::database::schema::Schema::default();
|
||||
ref_schema.obj.r#ref = Some(variation.clone());
|
||||
family_schemas.push(std::sync::Arc::new(ref_schema));
|
||||
}
|
||||
|
||||
return self.compile_one_of(&family_schemas, node);
|
||||
let mut all_targets = vec![family_target.clone()];
|
||||
if let Some(descendants) = self.db.descendants.get(family_target) {
|
||||
all_targets.extend(descendants.clone());
|
||||
}
|
||||
|
||||
if all_targets.len() == 1 {
|
||||
let mut bypass_schema = crate::database::schema::Schema::default();
|
||||
bypass_schema.obj.r#ref = Some(all_targets[0].clone());
|
||||
let mut bypass_node = node.clone();
|
||||
bypass_node.schema = std::sync::Arc::new(bypass_schema);
|
||||
return self.compile_node(bypass_node);
|
||||
}
|
||||
|
||||
all_targets.sort();
|
||||
let mut family_schemas = Vec::new();
|
||||
for variation in &all_targets {
|
||||
let mut ref_schema = crate::database::schema::Schema::default();
|
||||
ref_schema.obj.r#ref = Some(variation.clone());
|
||||
family_schemas.push(std::sync::Arc::new(ref_schema));
|
||||
}
|
||||
|
||||
return self.compile_one_of(&family_schemas, node);
|
||||
}
|
||||
|
||||
// Handle oneOf Polymorphism fallbacks for relations
|
||||
@ -230,49 +225,62 @@ impl<'a> Compiler<'a> {
|
||||
let mut select_args = Vec::new();
|
||||
|
||||
if let Some(family_target) = node.schema.obj.family.as_ref() {
|
||||
let base_type_name = family_target
|
||||
.split('.')
|
||||
.next_back()
|
||||
.unwrap_or(family_target)
|
||||
.to_string();
|
||||
let family_prefix = family_target.rfind('.').map(|idx| &family_target[..idx]);
|
||||
|
||||
if let Some(fam_type_def) = self.db.types.get(&base_type_name) {
|
||||
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 all_targets = vec![family_target.clone()];
|
||||
if let Some(descendants) = self.db.descendants.get(family_target) {
|
||||
all_targets.extend(descendants.clone());
|
||||
}
|
||||
|
||||
// Filter targets to EXACTLY match the family_target prefix
|
||||
let mut final_targets = Vec::new();
|
||||
for target in all_targets {
|
||||
let target_prefix = target.rfind('.').map(|idx| &target[..idx]);
|
||||
if target_prefix == family_prefix {
|
||||
final_targets.push(target);
|
||||
}
|
||||
}
|
||||
|
||||
final_targets.sort();
|
||||
final_targets.dedup();
|
||||
|
||||
if final_targets.len() == 1 {
|
||||
let variation = &final_targets[0];
|
||||
if let Some(target_schema) = self.db.schemas.get(variation) {
|
||||
let mut bypass_node = node.clone();
|
||||
bypass_node.schema = std::sync::Arc::new(bypass_schema);
|
||||
bypass_node.schema = std::sync::Arc::new(target_schema.clone());
|
||||
|
||||
let mut bypassed_args = self.compile_select_clause(r#type, table_aliases, bypass_node)?;
|
||||
select_args.append(&mut bypassed_args);
|
||||
} else {
|
||||
let mut family_schemas = Vec::new();
|
||||
let mut sorted_fam_variations: Vec<String> =
|
||||
fam_type_def.variations.iter().cloned().collect();
|
||||
sorted_fam_variations.sort();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
let base_alias = table_aliases
|
||||
.get(&r#type.name)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| node.parent_alias.to_string());
|
||||
select_args.push(format!("'id', {}.id", base_alias));
|
||||
let mut case_node = node.clone();
|
||||
case_node.parent_alias = base_alias.clone();
|
||||
let arc_aliases = std::sync::Arc::new(table_aliases.clone());
|
||||
case_node.parent_type_aliases = Some(arc_aliases);
|
||||
|
||||
let (case_sql, _) = self.compile_one_of(&family_schemas, case_node)?;
|
||||
select_args.push(format!("'type', {}", case_sql));
|
||||
return Err(format!("Could not find schema for variation {}", variation));
|
||||
}
|
||||
} else {
|
||||
let mut family_schemas = Vec::new();
|
||||
|
||||
for variation in &final_targets {
|
||||
if let Some(target_schema) = self.db.schemas.get(variation) {
|
||||
family_schemas.push(std::sync::Arc::new(target_schema.clone()));
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Could not find schema metadata for variation {}",
|
||||
variation
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let base_alias = table_aliases
|
||||
.get(&r#type.name)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| node.parent_alias.to_string());
|
||||
select_args.push(format!("'id', {}.id", base_alias));
|
||||
let mut case_node = node.clone();
|
||||
case_node.parent_alias = base_alias.clone();
|
||||
let arc_aliases = std::sync::Arc::new(table_aliases.clone());
|
||||
case_node.parent_type_aliases = Some(arc_aliases);
|
||||
|
||||
let (case_sql, _) = self.compile_one_of(&family_schemas, case_node)?;
|
||||
select_args.push(format!("'type', {}", case_sql));
|
||||
}
|
||||
} else if let Some(one_of) = &node.schema.obj.one_of {
|
||||
let base_alias = table_aliases
|
||||
@ -334,10 +342,7 @@ impl<'a> Compiler<'a> {
|
||||
};
|
||||
|
||||
for option_schema in schemas {
|
||||
if let Some(ref_id) = &option_schema.obj.r#ref {
|
||||
// Find the physical type this ref maps to
|
||||
let base_type_name = ref_id.split('.').next_back().unwrap_or("").to_string();
|
||||
|
||||
if let Some(base_type_name) = option_schema.obj.identifier() {
|
||||
// Generate the nested SQL for this specific target type
|
||||
let mut child_node = node.clone();
|
||||
child_node.schema = std::sync::Arc::clone(option_schema);
|
||||
|
||||
Reference in New Issue
Block a user