Bb 13.1 bar mdev 39563 - #5566
Conversation
…es the server The server crashed on DBUG_ASSERT on a SELECT into: - a `ROW TYPE OF table1` field variable - a `ROW TYPE OF cursor1` field variable Fix: - Adding a class my_var_sp_row_field_by_name - Adding a method sp_rcontext::set_variable_row_field_by_name() - Fixing the DBUG_ASSERT
|
|
There was a problem hiding this comment.
Pull request overview
Implements MDEV-39563 by extending the parser and execution pipeline to support UPDATE ... RETURNING ... INTO (Oracle mode), including support for assigning returned values into SP variables (including ROW/ROWTYPE fields) and assoc array scenarios, with new/updated MTR coverage.
Changes:
- Extend grammar to allow an optional
INTO <varlist>afterUPDATE ... RETURNING .... - Plumb
RETURNING ... INTOinto the UPDATE execution path by reusing a parse-timeselect_result(e.g.,select_dumpvar) when applicable. - Add/extend tests covering user variables, SP variables, ROW variables/fields, ROW TYPE OF (table/cursor), and assoc array behaviors; plus negative tests for unsupported DML contexts.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/sql_yacc.yy | Adds opt_into... support for RETURNING ... INTO and refactors INTO-varlist init rule reuse. |
| sql/sql_update.h | Adds a setter to inject a prebuilt select_result for UPDATE RETURNING. |
| sql/sql_update.cc | Adjusts returning result creation/reuse across executions (esp. SP/PS reuse). |
| sql/sql_type_row.cc | Adds runtime-by-name assignment path for ROWTYPE-based row-field OUT vars. |
| sql/sql_lex.h | Declares LEX::handle_returning_into_varlist(). |
| sql/sql_lex.cc | Implements LEX::handle_returning_into_varlist() to bind RETURNING ... INTO to UPDATE only. |
| sql/sp_rcontext.h | Declares set_variable_row_field_by_name() for runtime field lookup. |
| sql/sp_rcontext.cc | Implements runtime row-field assignment by field name. |
| plugin/type_assoc_array/mysql-test/type_assoc_array/sp-assoc-array-returning.test | New assoc-array focused test coverage for UPDATE RETURNING INTO. |
| plugin/type_assoc_array/mysql-test/type_assoc_array/sp-assoc-array-returning.result | Expected results for the new assoc-array tests. |
| mysql-test/main/update_returning.test | New core coverage for UPDATE RETURNING INTO, including ROW/ROWTYPE cases and repeated execution. |
| mysql-test/main/update_returning.result | Expected results for UPDATE RETURNING INTO tests. |
| mysql-test/main/update_returning_into_row_var.inc | Shared include for ROW/ROWTYPE INTO test permutations. |
| mysql-test/main/select_into_row.test | New coverage for SELECT INTO ROWTYPE field stability (MDEV-40790). |
| mysql-test/main/select_into_row.result | Expected results for SELECT INTO row tests. |
| mysql-test/main/replace_returning.test | Adds negative coverage for unsupported REPLACE ... RETURNING ... INTO. |
| mysql-test/main/replace_returning.result | Expected results for the new REPLACE negative test. |
| mysql-test/main/insert_returning.test | Adds negative coverage for unsupported INSERT ... RETURNING ... INTO. |
| mysql-test/main/insert_returning.result | Expected results for the new INSERT negative test. |
| mysql-test/main/delete_returning.test | Adds negative coverage for unsupported DELETE ... RETURNING ... INTO. |
| mysql-test/main/delete_returning.result | Expected results for the new DELETE negative test. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| bool LEX::handle_returning_into_varlist() | ||
| { | ||
| if (!result) | ||
| return false; // No INTO | ||
| if (m_sql_cmd) | ||
| { | ||
| Sql_cmd_update *update; | ||
| if ((update= dynamic_cast<Sql_cmd_update*>(m_sql_cmd))) | ||
| { | ||
| update->set_returning_result(result); | ||
| return false; | ||
| } | ||
| } | ||
| my_error(ER_NOT_ALLOWED_IN_THIS_CONTEXT, MYF(0), "RETURNING..INTO"); | ||
| return true; | ||
| } |
| int sp_rcontext::set_variable_row_field_by_name(THD *thd, uint var_idx, | ||
| const Lex_ident_sys_st &field_name, | ||
| Item **value) | ||
| { | ||
| DBUG_ENTER("sp_rcontext::set_variable_row_field"); | ||
| DBUG_ASSERT(value); | ||
| uint field_idx= 0; | ||
| if (find_row_field_by_name_or_error(&field_idx, var_idx, field_name)) | ||
| DBUG_RETURN(true); | ||
| Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx); | ||
| DBUG_RETURN(thd->sp_eval_expr(vtable->field[field_idx], value)); | ||
| } |
| bool check_assignability(THD *thd, const List<Item> &select_list, | ||
| bool *assign_as_row) const override | ||
| { | ||
| *assign_as_row= false; | ||
| return select_list.elements == 1; | ||
| } |
| else | ||
| { | ||
| /* | ||
| Otherwise it is: | ||
| 1. A non-RETURNING statement at all | ||
| 2. Or a statement returning into an SP variable list: | ||
| UPDATE t1 SET a=a+1 WHERE a=10 RETURNING a INTO va; | ||
| In this case returning_result was created during parse time | ||
| and we preserve it for the second and further executions. | ||
| */ | ||
| DBUG_ASSERT(!returning_result || | ||
| dynamic_cast<select_dumpvar*>(returning_result)); | ||
| } |
Adding support for UPDATE .. RETURNING .. INTO queries. For example: UPDATE t1 SET a=10,b=20 RETURNING a,b INTO va,vb; UPDATE t1 SET a=10,b=20 RETURNING a,b INTO @A,@b; Note, ANALYZE UPDATE .. RETURNING .. INTO queries work, ignoring the INTO clause. ANALYZE UPDATE t1 SET a=10,b=20 RETURNING a,b INTO va,vb; These types of queries: - REPLACE .. RETURNING .. INTO - DELETE .. RETURNING .. INTO do not work - they return an error. They will be implemented separately, when needed.
b6ebc97 to
a657340
Compare
This PR imlements MDEV-39563 Implement UPDATE ... RETURNING ... INTO