Skip to content

Promote the DuckDB IEJoin INTERSECTS implementation to a registered (DuckDBTarget, Intersects) override expander #169

Description

@conradbzura

Description

Migrate the DuckDB IEJoin column-to-column INTERSECTS join rewrite (IntersectsDuckDBIEJoinTransformer) from a pre-pass transformer into a registered, target-specific (DuckDBTarget, Intersects) override expander in the operator-expander registry. This is the DuckDB counterpart to #167 (which makes the naive overlap predicate the GenericTarget default and removes binning); together they move all INTERSECTS join strategy out of the pre-pass transformers and into the registry.

End state:

Motivation

Complete the operator-expander registry migration. The registry scaffolding (#138) and per-operator migrations landed for DISTANCE (#140), the INTERSECTS/CONTAINS/WITHIN predicates (#141), NEAREST (#142), DISJOIN (#143), and CLUSTER/MERGE (#144) — but the INTERSECTS join strategies (binned + DuckDB IEJoin) were left as pre-pass transformers selected by a hardcoded global capability branch. #167 removes the binned pre-pass and makes the GenericTarget default the naive predicate; this issue removes the IEJoin pre-pass and re-homes it as a registered DuckDB override, so INTERSECTS join strategy is fully registry-driven and target-overridable.

Expected Outcome

  • DuckDB column-to-column INTERSECTS joins are produced by a registered (DuckDBTarget, Intersects) override expander, not the pre-pass transformer.
  • The override declines outer joins (and any shape it cannot express) and defers to the GenericTarget naive-predicate default; no reliance on the removed binned transformer.
  • The global uses_iejoin branch in transpile.py is removed; strategy selection is via has_override.
  • Existing IEJoin results for supported shapes are preserved (regression), verified against DuckDB (oracle/integration test).

Interaction with existing IEJoin-dialect issues

With #167's naive predicate as the universal fallback, shapes the IEJoin override declines now defer to a capable default rather than the removed binned transformer. Several open IEJoin-dialect limitation issues may become closeable as "handled by the default" instead of requiring IEJoin support: #95 (LEFT/RIGHT JOIN), #96 (multiple INTERSECTS), #97 (self-joins), #98 (extra ON/WHERE predicates), #99 (bare */unqualified columns), #109 (top-level modifiers), #110 (CTEs/subquery operands), #111 (3+ tables). This issue makes a per-shape keep-in-IEJoin vs defer-to-default decision.

Relevant code

  • src/giql/transformer.pyIntersectsDuckDBIEJoinTransformer, _IEJoinSides, _has_outer_join_intersects, transform_to_sql (decline/None fallback), _classify_extras
  • src/giql/transpile.pyuses_iejoin gating (~156, 214-235), has_override seam (181)
  • src/giql/expander.pyExpanderRegistry, ExpansionContext, has_override
  • src/giql/targets.pyDuckDBTarget, Capabilities (range_join_strategy)

Dependencies

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorCode restructuring without behavior change

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions