fixed issue with STI on non-tables

This commit is contained in:
2026-05-12 08:22:25 -04:00
parent 6cc4f4ad86
commit 1fb378def2
6 changed files with 164 additions and 147 deletions

View File

@ -9,7 +9,7 @@ impl Schema {
errors: &mut Vec<crate::drop::Error>,
) {
let mut options = std::collections::BTreeMap::new();
let mut strategy = String::new();
let strategy: &str;
if let Some(family) = &self.obj.family {
// Formalize the <Variant>.<Base> topology
@ -24,7 +24,7 @@ impl Schema {
if let Some(type_def) = db.types.get(&family_base) {
if type_def.variations.len() > 1 && type_def.variations.iter().any(|v| v != &family_base) {
// Scenario A / B: Table Variations
strategy = "type".to_string();
strategy = "type";
for var in &type_def.variations {
let target_id = if family_prefix.is_empty() {
var.to_string()
@ -38,7 +38,7 @@ impl Schema {
}
} else {
// Scenario C: Single Table Inheritance (Horizontal)
strategy = "kind".to_string();
strategy = "kind";
let suffix = format!(".{}", family_base);
@ -50,6 +50,19 @@ impl Schema {
}
}
}
} else {
// Scenario D: Field-Backed JSONB Bubble STI (No explicit table representation)
strategy = "kind";
let suffix = format!(".{}", family_base);
// Scan the entire database schemas registry for matching suffixes
for (id, schema) in &db.schemas {
if id.ends_with(&suffix) || id == &family_base {
if let Some(kind_val) = schema.obj.get_discriminator_value("kind", id) {
options.insert(kind_val, (None, Some(id.to_string())));
}
}
}
}
} else if let Some(one_of) = &self.obj.one_of {
let mut type_vals = std::collections::HashSet::new();
@ -84,7 +97,7 @@ impl Schema {
}
if disjoint_base && structural_types.len() == one_of.len() {
strategy = "".to_string();
strategy = "";
for (i, c) in one_of.iter().enumerate() {
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &c.obj.type_ {
if crate::database::object::is_primitive_type(t) {
@ -96,11 +109,11 @@ impl Schema {
}
} else {
strategy = if type_vals.len() > 1 && type_vals.len() == one_of.len() {
"type".to_string()
"type"
} else if kind_vals.len() > 1 && kind_vals.len() == one_of.len() {
"kind".to_string()
"kind"
} else {
"".to_string()
""
};
if strategy.is_empty() {
@ -148,7 +161,7 @@ impl Schema {
if !options.is_empty() {
if !strategy.is_empty() {
let _ = self.obj.compiled_discriminator.set(strategy);
let _ = self.obj.compiled_discriminator.set(strategy.to_string());
}
let _ = self.obj.compiled_options.set(options);
}