Repository navigation
fix(postgres): null what an outer-joined with query reads - #18
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Important
The fix is sound for SELECT WITH queries, but one shape of the same bug remains: a data-modifying WITH query on the nullable side of an outer join is still typed non-null (inline). This predates the PR — it fails on main too — but the new with_tables is meant to cover exactly this case.
Reviewed changes
Reviewed the single commit that nulls the relations an outer-joined WITH query reads, so a * traced through the query to its table no longer keeps the catalog's NOT NULL.
Analysis::with_tables/nulled_tables— each CTE name maps to the relations itsctequeryreads, closed over the WITH queries it reads in turn.nulled_tablesadds them for every nulled CTE.unreducedinpostgres.rs— appliesnulled_tablesafter the WHERE/ON reductions and the untrusted-witness put-back, so a CTE that a strict predicate reduces brings nothing.- Oracle cases —
with_star_left_join_nulled.sqlandwith_star_nested_nulled.sql, plus the rebuiltengine.wasm.
Verified locally at 3220aa1:
cargo test -p reylo-engine-postgres --libpasses (141 tests).- The oracle's
derived_tables(35 statements) andjoins(18 statements) cases pass on PG16. The new case fails onmain, as the PR says. - Scratch probes typed correctly: a WHERE-reduced CTE, a RIGHT JOIN, a CTE reached through a derived table, a view inside the CTE, and a join inside the CTE.
- Nulling a relation that is also read elsewhere in the statement costs nothing in practice. Such a statement already sets
has_repeated_table, so its columns are all nullable throughhiddenanyway.
claude-opus-5-5 | 𝕏
3220aa1 to
4a1e41b
Compare
The describe traces a column read through a WITH query to the table inside it, so `select *` over an outer-joined WITH query typed that query's columns from the table's NOT NULL.
4a1e41b to
69a1d14
Compare
There was a problem hiding this comment.
✅ No new issues found. The data-modifying WITH query case from the prior review is fixed and pinned by a test.
Reviewed changes
I reviewed 69a1d14, the commit that nulls the target of an outer-joined data-modifying WITH query.
- DML target in
with_tables— collecting a WITH query's read set now also walksctequeryand adds therelation.relnameof anyInsertStmt/UpdateStmt/DeleteStmt/MergeStmt. It reads the field the same wayanalyze.rs:227already does. Nothing else needs to change, becausenulled_tablesandunreducedconsume the list as before. - Coverage — there is a new assertion in
an_outer_join_that_nulls_a_with_query_nulls_what_it_readsand a new oracle case,derived_tables/with_insert_left_join_nulled.sql. It uses the non-colliding key-424242, so the INSERT actually runs under seeding.
I checked this locally at 69a1d14:
cargo test -p reylo-engine-postgres --lib: 145 passed.- The oracle
derived_tablescase passes all 36 statements on PG16, including the new one.
claude-opus-5-5 | 𝕏

An unqualified
*over several FROM items, one of them a WITH query on the nullable side of an outer join, typed that query's columns as non-null:The describe traces a column read through a WITH query to the table inside it, while the outer join nulls the query by its own name. A column read by name (
t.label) was settled from the query's own probe, but a*across several items maps no column to its item, so it fell back to the table'sNOT NULL.Now an outer join that nulls a WITH query also nulls every relation the query reads, through the WITH queries it reads in turn, after the strict WHERE and ON reductions have had their say. A relation read inside the nulled query and again elsewhere in the statement is nulled there too, which is how a derived table on the nullable side already behaves.
oracle/cases/derived_tables:with_star_left_join_nulled.sqlandwith_star_nested_nulled.sql(both failed the oracle's seeded check before).packages/postgres/engine.wasmrebuilt.