[mysql] Add Fallback to column scanning when column_names is empty for stored procedures#4197
[mysql] Add Fallback to column scanning when column_names is empty for stored procedures#4197romeoneverdies wants to merge 4 commits intolaunchbadge:mainfrom
Conversation
There was a problem hiding this comment.
Add a fallback in the ColumnIndex impl for &str:
- First try the existing
column_namesmap (unchanged fast path for normal queries)- On miss: scan row.columns by comparing col.name.as_ref() to the requested name
This is only a half-fix. A MariaDB maintainer made the point that we should always use the actual resultset header as the source of truth for columns. Lots of different things can happen to change what columns come back from a query, especially in the case of SELECT *. Ultimately, the column set we get from COM_STMT_PREPARE_OK should be treated as purely informational.
The actual fix here is to just always populate the hashmap from the resultset.
Linear scan over columns (typically < 20 → negligible performance impact)
It doesn't need to happen here, but one of the refactors I've been thinking we should do is separate FromRow into two separate phases:
- resolution of column names to offsets, which happens once at the beginning of the resultset.
- when decoding rows, use the previously calculated offsets instead of looking up by column name.
This would eliminate the need to have any sort of lookup overhead when decoding resultsets, which should really improve performance for queries that return many rows.
|
Problem
When executing a MySQL/MariaDB stored procedure with
CALL, theMySqlRow.column_namesmap is often empty due to MySQL protocol limitations on procedure result sets. This causesrow.try_get("column_name")to fail withColumnNotFound, forcing users to use positional indexing (try_get(0), etc.) as a workaround.See: #1742 (open since 2022)
Solution
Add a fallback in the
ColumnIndex<MySqlRow>impl for&str:column_namesmap (unchanged fast path for normal queries)row.columnsby comparingcol.name.as_ref()to the requested nameColumnNotFounderrorThis enables reliable named access after
CALLprocedures without changing any user code.Trade-offs
OnceCell+Mutex)Related
Fixes #1530
Closes #1742
Similar reports in #2206, Stack Overflow, etc.
Happy to add integration tests, make it opt-in (feature flag), or adjust based on feedback.