Class JoinPathResolver
JoinResolution.
The model does extraction (which relations/columns/filters the user wants); this does structure (the join over the graph). Given a generated program, it finds the base-relation join at its core (a stack of unary operators over a region of joins over relation leaves), maps the leaves to graph terminals, and searches the graph:
- unique minimal path → rewrite the join region with graph-derived
equijoin conditions, correcting a wrong FK guess (
JoinResolution.Resolved); - ambiguous → enumerate the paths by relationship name for a
"did you mean?" (
JoinResolution.Ambiguous— the two-FKissues → userscase); - anything the graph cannot improve →
JoinResolution.Passthrough.
Safety scope. The rewrite fires only when it is provably semantics-
preserving: the join region must be a pure tree of joins over distinct
base-relation leaves (no filter/projection buried inside it, no self-join), and
the graph path must span exactly that leaf set — so only the join
conditions change, never the set of tables or their left-to-right order (which
keeps collided-column _r disambiguation stable). Anything outside that
envelope — a missing intermediate table, an aggregate mid-join, a multi-
statement program — is passed through untouched. Inserting a missing table and
resolving a qualified-column collision are outside its scope.
Bounds facts (JoinResolution.BoundsFacts) are computed and carried for
tracing only; nothing surfaces the fan-out / row-drop they describe to the user.
-
Method Summary
Modifier and TypeMethodDescriptionstatic JoinResolutionresolve(SchemaGraph graph, SymbolTable symbols, RelNode program) Resolves the join inprogramagainstgraph.
-
Method Details
-
resolve
Resolves the join inprogramagainstgraph.- Parameters:
graph- the schema relationship graph (empty → always passthrough)symbols- the symbol table the program's relation names resolve againstprogram- the generated query's root relational-algebra node- Returns:
- the resolution outcome; never null
-