MDEV-40303 SIGSEGV in Item_field::type_handler() on PS re-execution#5425
MDEV-40303 SIGSEGV in Item_field::type_handler() on PS re-execution#5425forkfun wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses a crash (MDEV-40303) that occurs when re-executing a prepared statement that reads a derived-table column holding a scalar UNION subquery. The fix ensures that a unit that was cleaned up but left "prepared" is properly re-prepared by calling unclean(), clearing types, and re-initializing the execution mechanism. Additionally, a comprehensive test case test_mdev_40303 has been added to verify this behavior. I have no further feedback to provide as the changes are clean and well-tested.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
Fixes a server crash when re-executing a prepared statement that reads a derived-table column containing a scalar UNION subquery, by ensuring a st_select_lex_unit that has been cleanup()’d (but still marked prepared) is fully re-prepared on the next prepare().
Changes:
- In
st_select_lex_unit::prepare(), detect the invalid state(prepared && cleaned)and reset execution/preparation state so the unit is re-prepared instead of using stale lists. - Add a mysql_client_test reproducer that executes once normally, then re-executes via raw
COM_STMT_EXECUTEwith a GEOMETRY-typed parameter and asserts an error (no crash).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/mysql_client_test.c | Adds a regression test for MDEV-40303 using a prepared statement re-execution path that previously triggered the crash. |
| sql/sql_union.cc | Resets unit state when cleanup() left the unit marked prepared, forcing a safe re-prepare on subsequent executions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
sanja-byelkin
left a comment
There was a problem hiding this comment.
I do not understand why both flags set
|
|
||
| /* A unit cleanup() tore down but left "prepared" must be re-prepared, | ||
| else set_row() walks its stale item_list (NULL fields) on re-fix. */ | ||
| if (prepared && cleaned) |
Re-executing a prepared statement that reads a derived-table column holding a scalar UNION subquery crashed the server: between executions st_select_lex_unit::cleanup() frees union_result and sets 'cleaned' but leaves 'prepared' set, so on re-fix set_row() walks a stale item_list whose Item_field::field are NULL. Fix: prepare() re-prepares a cleaned unit instead of treating it as still prepared.
44ea7d0 to
2af11a8
Compare
Re-executing a prepared statement that reads a derived-table column
holding a scalar UNION subquery crashed the server: between executions
st_select_lex_unit::cleanup() frees union_result and sets 'cleaned' but
leaves 'prepared' set, so on re-fix set_row() walks a stale item_list
whose Item_field::field are NULL.
Fix: prepare() re-prepares a cleaned unit instead of treating it as
still prepared.