8000 fix(mysql): type a parameter by a derived table's column by colinhacks · Pull Request #125 · colinhacks/reylo · GitHub
[go: up one dir, main page]

Skip to content

fix(mysql): type a parameter by a derived table's column - #125

Merged
colinhacks merged 2 commits into
mainfrom
mysql-derived-param-types
Oct 26, 2026
Merged

colinhacks merged 2 commits into
mainfrom
mysql-derived-param-types

Conversation

@colinhacks
Copy link
Copy Markdown
Owner

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. So select * from (select id, title from posts) s where s.id = :id typed id as int4 for a BIGINT key, where select * from posts where id = :id types it int8, 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, * and q.* 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

  • 24 oracle answers move from int4 to int8 (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, and nub run test with both test databases: 271 pass, none skipped.

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.
@vercel
vercel Bot commented Oct 26, 2026 •
Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
reylo Ignored Ignored Preview Oct 26, 2026 7:05pm UTC

Request Review

Copilot AI balanced review requested due to automatic review settings October 26, 2026 18:54
Copilot AI left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ 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_origin in mysql_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.
  • compared in mysql_params — resolves s.col, and a bare col over 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 through typed_tables → written_tables(typed_targets).
  • Oracle and artifact — 24 answers go from int4 to int8 in mysql_subquery_keys and mysql_limits, each a BIGINT key compared through a derived table or a WITH query. packages/mysql/engine.wasm is rebuilt.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread engine/mysql/src/mysql_keys.rs Resolved
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.
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 sets plain = false and 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 how From::factor resolves names.
  • Oracle coverage. two_withs now answers id: int8. The new with_shadows_table and with_sibling_shadow cases, built on a flags table with a tinyint(1) key, confirm a WITH query named like a table does not pick up that table's bool|int4.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@colinhacks
colinhacks merged commit a86b6b6 into main Oct 26, 2026
9 checks passed
@colinhacks
colinhacks deleted the mysql-derived-param-types branch October 26, 2026 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0