Optimizer drops LEFT JOIN when a cast collapses distinct join keys

Closed
#8,858 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@finnhoang05 is already working on this.

Since Oct 31, 2026.

  • #8859 by @finnhoang05 — open

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
30/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
python, sql

Research direction

The bug is in _is_joined_on_all_unique_outputs in the sqlglot optimizer; read that function to see how it compares join keys by .name. Run the provided Python repro to confirm the dropped rows, then adjust the uniqueness check to account for casts. Done means the optimized SQL keeps the LEFT JOIN and returns three rows.

Written by the indexing model from the issue text.

Description

The optimizer removes a LEFT JOIN when its right-hand key is a cast of a distinct column. Distinct timestamps can become the same date after the cast, so removing the join changes the number of rows returned.

Reproduced on main at 6de2df31b0ae8b21155828f575a14dc8903c1b9b, with Python 3.12 and DuckDB 2.0.0. Both the read and write dialects are DuckDB.

import duckdb
from sqlglot import parse_one
from sqlglot.optimizer import optimize

sql = """
SELECT days.day
FROM (VALUES (DATE '2026-10-30'), (DATE '2026-10-31')) AS days(day)
LEFT JOIN (
    SELECT DISTINCT events.occurred_at
    FROM (VALUES
        (TIMESTAMP '2026-10-30 09:00:00'),
        (TIMESTAMP '2026-10-30 18:00:00')
    ) AS events(occurred_at)
) AS event_times ON days.day = CAST(event_times.occurred_at AS DATE)
ORDER BY days.day
"""

optimized = optimize(parse_one(sql, read="duckdb"), dialect="duckdb").sql("duckdb")
with duckdb.connect() as conn:
    original = conn.execute(sql).fetchall()
    rewritten = conn.execute(optimized).fetchall()
print("original:", [str(row[0]) for row in original])
print("optimized:", [str(row[0]) for row in rewritten])
print(optimized)

Output:

original: ['2026-10-30', '2026-10-30', '2026-10-31']
optimized: ['2026-10-30', '2026-10-31']

The optimized query should preserve all three rows: both events match October 30, and October 31 has no match. The generated SQL currently has no join. TRY_CAST and replacing DISTINCT with GROUP BY events.occurred_at also reproduce the issue.

The cause appears to be _is_joined_on_all_unique_outputs: it compares join_keys by .name, and Cast.name returns the underlying column name without proving that the cast preserves uniqueness.

DuckDB references: casts and join semantics.

Found with Codex assistance.

Dominant language
Python
Stars
9.8k
Forks
1.4k
Avg merge
14h 12m
Merged PRs (30d)
225

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.