Skip to content

Conversation

@borodark
Copy link

@borodark borodark commented Jan 14, 2026

Summary

Closes #10307
Tested and verified in this PR: borodark/power_of_three#7
This PR fixes Postgrex/Ecto connectivity to Cube SQL API by addressing two issues:

  1. LEFT JOIN with OR conditions - DataFusion converts these to Filter(CrossJoin), losing LEFT JOIN semantics and causing type bootstrap to fail
  2. Missing pg_type columns - typsend, typoutput, typreceive columns were missing or NULL

Changes

New Files

  • rust/cubesql/cubesql/src/compile/engine/df/optimizers/cross_join_to_left_join.rs

    New optimizer rule that detects Filter(CrossJoin) patterns for pg_catalog tables and converts them back to proper LeftJoin operations.

    Key features:

    • Identifies pg_catalog table scans by schema characteristics (not table names, which are aliases)
    • Extracts equi-join columns from OR/AND predicates
    • Handles nested JOIN structures
    • Only activates for pg_catalog queries to avoid affecting user queries

Modified Files

  • rust/cubesql/cubesql/src/compile/engine/df/optimizers/mod.rs

    • Export new CrossJoinToLeftJoin optimizer
  • rust/cubesql/cubesql/src/compile/query_engine.rs

    • Add CrossJoinToLeftJoin to optimizer pipeline (runs first)
  • rust/cubesql/cubesql/src/compile/engine/information_schema/postgres/pg_type.rs

    • Add typsend, typoutput, typreceive columns with proper OID values
  • rust/cubesql/pg-srv/src/pg_type.rs

    • Add type metadata for binary/text I/O functions

Test Updates

  • Updated DBeaver and PowerBI introspection snapshots to reflect new pg_type columns

Testing

  • All 655 unit tests pass
  • Clippy clean
  • Format check passes
  • Manual testing with Elixir/Postgrex/Ecto confirms:
    • Type bootstrap completes successfully
    • Basic queries work (Repo.all, Repo.one)
    • Filtering works (where: field == ^value)
    • Aggregation works (group_by, sum, count)

Example Usage

After this fix, Elixir developers can query Cube using familiar Ecto patterns:

# Define Ecto schema for a Cube view
defmodule MyCubes.Orders do
  use Ecto.Schema
  @primary_key {:id, :float, autogenerate: false}

  schema "orders_no_preagg" do
    field :brand_code, :string
    field :total_amount_sum, :float
    field :count, :integer
  end
end

# Query using standard Ecto
import Ecto.Query

query = from o in MyCubes.Orders,
  where: o.brand_code == "Heineken",
  group_by: o.brand_code,
  select: {o.brand_code, sum(o.total_amount_sum)},
  limit: 10

Cubes.Repo.all(query)
# => [{"Heineken", 34968575.0}]

Closes

Closes #10307 (Postgrex/Ecto type bootstrap fails with pg_catalog LEFT JOIN queries)

borodark and others added 5 commits January 13, 2026 17:46
- Fix clippy warning for useless .into_iter() in cross_join_to_left_join
- Apply cargo fmt formatting to cross_join_to_left_join.rs
- Update DBeaver and PowerBI introspection snapshots for pg_type changes

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@borodark borodark requested a review from a team as a code owner January 14, 2026 02:09
@github-actions github-actions bot added rust Pull requests that update Rust code pr:community Contribution from Cube.js community members. labels Jan 14, 2026
@borodark borodark force-pushed the feature/ecto-adbc-postgres branch from 5316d22 to 7f30707 Compare January 14, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:community Contribution from Cube.js community members. rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cube SQL pg_type returns NULL instead of 0 for typsend/typoutput

1 participant