Repository navigation
fix(mysql): type a parameter by a derived table's column - #125
Conversation
A parameter compared with a column of a derived table or a WITH query takes the type of the table column it passes through, as one compared with the table's own column does: a BIGINT column's is int8, not the prepare's int4.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
ℹ️ One rough edge worth a look — the WITH scope is dropped when a derived table or a WITH query reads another WITH query.
Reviewed changes
Reviewed the whole PR: how a compared parameter is now typed through a derived table or a WITH query on MySQL.
output_origininmysql_keys— follows an output column of a query through its select list (a bare column, an alias,*over one item,q.*) down nested subqueries to the table column it passes through, without the catalog.comparedinmysql_params— resolvess.col, and a barecolover a single FROM item, through a non-lateral derived table or a top-level non-recursive WITH query that renames no columns. The origin table reaches the catalog query throughtyped_tables→written_tables(typed_targets).- Oracle and artifact — 24 answers go from
int4toint8inmysql_subquery_keysandmysql_limits, each a BIGINT key compared through a derived table or a WITH query.packages/mysql/engine.wasmis rebuilt.
claude-opus-5-5 | 𝕏
A name one of the statement's WITH queries has is that query, never a table, at the top level and in the trace through a derived table or a WITH query's body; a recursive WITH query, or one that renames its columns, gives no column at all.
There was a problem hiding this comment.
✅ No new issues found. The WITH scope now carries through the whole walk.
Reviewed changes
Reviewed cf78bc3, which fixes how WITH queries are scoped when a compared parameter is read through a derived table or a WITH query.
- Scope built once in
compared.ctes_of(q, &[])now builds the statement's WITH scope, and a top-level name that matches a WITH query is always that query, never a base table. A WITH query that is recursive or renames its columns setsplain = falseand gives no column. - Scope passed to
output_origin. A WITH query's body gets only the WITH queries listed before it (&ctes[..sees]), and a top-level derived table gets all of them. Inside the walk this matches howFrom::factorresolves names. - Oracle coverage.
two_withsnow answersid: int8. The newwith_shadows_tableandwith_sibling_shadowcases, built on aflagstable with atinyint(1)key, confirm a WITH query named like a table does not pick up that table'sbool|int4.
claude-opus-5-5 | 𝕏

On MySQL, a parameter compared with a column of a derived table or a WITH query kept the prepare's type, which describes every integer context as
int4. Soselect * from (select id, title from posts) s where s.id = :idtypedidasint4for a BIGINT key, whereselect * from posts where id = :idtypes itint8, and a caller could not pass a key past 2^31 without a type error.The compared columns are now read through a derived table or a WITH query to the table column each passes through unchanged (
mysql_keys::output_origin, which follows the select list,*andq.*down nested subqueries). The parameter then takes that column's type, as it does for the table's own column.A parameter compared inside a subquery's own WHERE, or in a join's ON, keeps the prepare's type. That is how a plain table's is read today, since only the top-level WHERE and HAVING are walked.
Checks
int4toint8(mysql_subquery_keys,mysql_limits/derived_limit), each a parameter compared with a BIGINT column through a derived table or a WITH query. The whole oracle passes with--strict-coverage(154 cases).cargo test -p reylo-engine-mysql, andnub run testwith both test databases: 271 pass, none skipped.