1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-28965 Assertion failure when preparing UPDATE with derived table in WHERE

This patch fixes not only the assertion failure in the function
Field_iterator_table_ref::set_field_iterator() but also:
 - fixes the problem of forced materialization of derived tables used
   in subqueries contained in WHERE clauses of single-table and multi-table
   UPDATE and DELETE statements
 - fixes the problem of MDEV-17954 that prevented execution of multi-table
   DELETE statements if they use in their WHERE clauses references to
   the tables that are updated.

The patch must be considered a complement to the patch for MDEV-28883.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
Igor Babaev
2022-07-11 16:57:37 -07:00
parent 3a9358a410
commit 88ca62dc68
27 changed files with 1106 additions and 79 deletions

View File

@@ -40,6 +40,8 @@
#ifdef WITH_WSREP
#include "mysql/service_wsrep.h"
#endif
#include "sql_update.h" // class Sql_cmd_update
#include "sql_delete.h" // class Sql_cmd_delete
void LEX::parse_error(uint err_number)
{
@@ -4026,9 +4028,8 @@ bool LEX::can_use_merged()
SYNOPSIS
LEX::can_not_use_merged()
@param no_update_or_delete Set to 1 if we can't use merge with multiple-table
updates, like when used from
TALE_LIST::init_derived()
@param forced_no_merge_for_update_delete Set to 1 if we can't use merge with
multiple-table updates/deletes
DESCRIPTION
Temporary table algorithm will be used on all SELECT levels for queries
@@ -4039,7 +4040,7 @@ bool LEX::can_use_merged()
TRUE - VIEWs with MERGE algorithms can be used
*/
bool LEX::can_not_use_merged(bool no_update_or_delete)
bool LEX::can_not_use_merged(bool forced_no_merge_for_update_delete)
{
switch (sql_command) {
case SQLCOM_CREATE_VIEW:
@@ -4053,18 +4054,29 @@ bool LEX::can_not_use_merged(bool no_update_or_delete)
return TRUE;
case SQLCOM_UPDATE_MULTI:
case SQLCOM_DELETE_MULTI:
if (no_update_or_delete)
if (forced_no_merge_for_update_delete)
return TRUE;
/* Fall through */
case SQLCOM_UPDATE:
if (no_update_or_delete && m_sql_cmd &&
(m_sql_cmd->sql_command_code() == SQLCOM_UPDATE_MULTI ||
if (forced_no_merge_for_update_delete &&
(((Sql_cmd_update *) m_sql_cmd)->is_multitable() ||
query_tables->is_multitable()))
return TRUE;
return FALSE;
case SQLCOM_DELETE_MULTI:
if (forced_no_merge_for_update_delete)
return TRUE;
/* Fall through */
case SQLCOM_DELETE:
if (forced_no_merge_for_update_delete &&
(((Sql_cmd_delete *) m_sql_cmd)->is_multitable() ||
query_tables->is_multitable()))
return TRUE;
return FALSE;
default:
return FALSE;
}