diff --git a/src/database/mod.rs b/src/database/mod.rs index afa6eb8..cec3b44 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -500,6 +500,22 @@ impl Database { let is_reverse = p_def.hierarchy.contains(&rel.destination_type) && c_def.hierarchy.contains(&rel.source_type); + // A self-referential edge on a shared ancestor table (entity.parent_id -> entity) matches + // both ways for every type pair. An array can only be the reverse (one-to-many) side; a + // scalar is the forward side only when the property IS the pointer (`parent` for + // `parent_id`) — otherwise it is the single child that points here (a cover attachment). + if is_forward && is_reverse { + let stem = rel + .source_columns + .first() + .map(|c| c.trim_end_matches("_id")) + .unwrap_or(""); + let names_pointer = !stem.is_empty() && prop_name == stem; + if is_array || !names_pointer { + is_forward = false; + } + } + // Structural Cardinality Filtration: // If the schema requires a collection (Array), it is mathematically impossible for a pure // Forward scalar edge (where the parent holds exactly one UUID pointer) to fulfill a One-to-Many request.