fix(mysql): type untyped expression columns by value (SELECT 1 gone-away) - #8
Merged
Merged
Conversation
A prepared `SELECT 1` (or any table-less expression: `SELECT a+b`,
`SELECT 7 AS x`) dropped the connection with "2006 server has gone
away". SQLite gives expression columns no declared type, so decltype
is None and sqlite_to_mysql_column_type fell back to VAR_STRING — but
the row writer emits each value natively (an integer as LONGLONG), and
opensrv's binary protocol rejects the declared/actual mismatch
("tried to use 1 as MYSQL_TYPE_VAR_STRING") and closes the socket.
Fix: for columns with no decltype, derive the wire type from the first
non-NULL value in the result set (mysql_type_for_value), so the
declared column type matches how the value is encoded. Declared-type
columns are unchanged; all-NULL/empty columns stay VAR_STRING (NULL is
valid against any type).
Regression test prepared_select_expression_no_table covers SELECT 1,
a multi-column expression select, and an aliased expression. Found via
ePHPm DB probing; only bit clients that disable PDO prepare-emulation
(Doctrine-style) and issue a real-prepared expression query.
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.
Summary
SELECT 1(or any table-less expression:SELECT a+b,SELECT 7 AS x) dropped the connection with 2006 server has gone away.decltype = None→sqlite_to_mysql_column_typefell back toVAR_STRING. But the row writer emits each value natively (integer → LONGLONG), and opensrv's binary protocol rejects the declared/actual mismatch (tried to use 1 as MYSQL_TYPE_VAR_STRING) and closes the socket.decltype, derive the wire type from the first non-NULL value (mysql_type_for_value). Declared-type columns unchanged; all-NULL/empty columns stayVAR_STRING.Test
prepared_select_expression_no_table(SELECT 1, multi-column expression, aliased expression) — fails before, passes after.mysql_e2esuite: 24 passed. clippy-D warnings+ fmt clean.Found during ePHPm's DB verification. Impact: bit clients that disable PDO prepare-emulation (Doctrine-style) and issue a real-prepared expression query; direct
COM_QUERYwas unaffected. Not a v0.4.1 blocker (table queries work) but a clean correctness fix for the follow-up.