Repository navigation
fix(mysql): probe a scalar subquery's items with its own with - #29
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
I reviewed the whole PR. It changes how the MySQL JSON-shape planner probes a scalar subquery's items, so that a subquery's own WITH reaches its probe.
- Per-level
WITH.Builder.stacknow holdsLevel { ctx, from, with }, so each scalar subquery level keeps its query'sWITH, and eachDraftcarries theWITHtext its probe starts with. carriedflattens the levels. It joins every level'sWITH, outermost first, into one list. If any level isRECURSIVE, the list is too, and it makes no probe when a query at a non-RECURSIVElevel names itself. Top-level probes print the same as before.- Wider form guarded.
draft()drops the wider form when an enclosingFROMnames aWITHquery from a level inside it. A subquery with noFROMof its own gets no probe in that case. - Tests. There is a new
mysql_shapeunit test for the probe text, a new oracle caseoracle/cases/mysql_subquery_withwith 15 statements, and a rebuiltpackages/mysql/engine.wasm.
I traced how names resolve in the flattened list against the nested statement:
- Unique names read the same in both.
- A name listed twice is refused by the server, so the probe fails and the server's flag stands. Before this PR, the same case read the outer query's definition, which was unsound.
- Correlated inner
WITHqueries fail to prepare in both the narrow and the wider form, so they stay untyped rather than being typed wrongly.nested_correlated.sqlis an example.
probe_flow doesn't depend on where a ? sits, so the extra placeholders from the carried WITH queries don't misalign anything. cargo test -p reylo-engine-mysql --lib mysql_shape passes locally (10/10).
claude-opus-5-5 | 𝕏
This was referenced Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

On MySQL, a scalar subquery with a WITH of its own was typed more loosely than the same statement with the WITH outside:
nwasint8?; it is nowint8, since an ungrouped aggregate is exactly one row.The engine types each item of a scalar subquery by preparing a probe: the item selected over the subquery's FROM. That probe was printed with the outer statement's WITH only, so
SELECT count(id) FROM rfailed to prepare and the column fell back to the server's flag. A JSON object's fields over such a WITH came outunknown?for the same reason.The same gap was also unsound when the subquery's WITH query shadows a table. The probe read the table in its place, so here
titlewas typed non-null fromposts.titlewhile the query yields NULL (the oracle finds it on seeded runs):Now each level the builder walks keeps its query's WITH, and a probe starts with the WITH queries of every level from the statement down, as one list:
Tests:
mysql_shapeunit test for the probe text: the subquery's own WITH, the statement's before it, nested levels, sibling subqueries, a derived table reading the WITH, RECURSIVE, a WITH that shadows a table, and each refusal.oracle/cases/mysql_subquery_with, 15 statements, all run on MySQL 8.4 over seeded values with none unchecked. Before → after:own_count,own_count_correlated,outer_and_own,derived_reads_with:int8?→int8own_json,nested: fieldsunknown?→ typed, and non-null where the columns arerecursive:countint8?→int8;sumstaysnumeric?shadows_table:title: text→text?(the old type was contradicted by the seeded runs)own_max,own_json_unguarded,recursive_beside_self_named,wider_shadowed,with_inside_derived,shadows_table_count: unchangedmysql_*oracle case passes with--strict-coverage, and no existingexpected.txtchanges.packages/mysql/engine.wasmis rebuilt.