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

Merge remote-tracking branch 'github/bb-11.4-release' into bb-11.8-serg

This commit is contained in:
Sergei Golubchik
2025-04-27 11:33:27 +02:00
committed by Oleksandr Byelkin
430 changed files with 14769 additions and 6751 deletions

View File

@@ -19,6 +19,7 @@
#include "mariadb.h"
#include "sql_base.h" // setup_table_map
#include "sql_list.h"
#include "sql_priv.h"
#include "unireg.h"
#include "debug_sync.h"
@@ -1180,7 +1181,6 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
const Lex_ident_table t_name= table->table_name;
const Lex_ident_table t_alias= table->alias;
retry:
DBUG_PRINT("info", ("real table: %s.%s", d_name.str, t_name.str));
for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0)
{
@@ -1253,43 +1253,73 @@ retry:
TABLE_LIST *derived= res->belong_to_derived;
if (derived->is_merged_derived() && !derived->derived->is_excluded())
{
bool materialize= true;
if (thd->lex->sql_command == SQLCOM_UPDATE)
{
Sql_cmd_update *cmd= (Sql_cmd_update *) (thd->lex->m_sql_cmd);
if (cmd->is_multitable() || derived->derived->outer_select())
materialize= false;
else if (!cmd->processing_as_multitable_update_prohibited(thd))
if (!(cmd->is_multitable() || derived->derived->outer_select()) &&
(!cmd->processing_as_multitable_update_prohibited(thd)))
{
cmd->set_as_multitable();
materialize= false;
}
}
else if (thd->lex->sql_command == SQLCOM_DELETE)
{
{
Sql_cmd_delete *cmd= (Sql_cmd_delete *) (thd->lex->m_sql_cmd);
if (cmd->is_multitable() || derived->derived->outer_select())
materialize= false;
else if (!cmd->processing_as_multitable_delete_prohibited(thd))
if (!(cmd->is_multitable() || derived->derived->outer_select()) &&
(!cmd->processing_as_multitable_delete_prohibited(thd)))
{
cmd->set_as_multitable();
materialize= false;
}
}
if (materialize)
{
DBUG_PRINT("info",
("convert merged to materialization to resolve the conflict"));
derived->change_refs_to_fields();
derived->set_materialized_derived();
goto retry;
}
}
}
DBUG_RETURN(res);
}
TABLE_LIST* unique_table_in_select_list(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
{
subselect_table_finder_param param= {thd, table, NULL};
List_iterator_fast<Item> it(sel->item_list);
Item *item;
while ((item= it++))
{
if (item->walk(&Item::subselect_table_finder_processor, FALSE, &param))
{
if (param.dup == NULL)
return ERROR_TABLE;
return param.dup;
}
DBUG_ASSERT(param.dup == NULL);
}
return NULL;
}
typedef TABLE_LIST* (*find_table_callback)(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel);
static
TABLE_LIST*
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel, find_table_callback callback );
TABLE_LIST* unique_table_callback(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel)
{
return find_dup_table(thd, table, table_list, check_flag);
}
TABLE_LIST* unique_in_sel_table_callback(THD *thd, TABLE_LIST *table,
TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel)
{
return unique_table_in_select_list(thd, table, sel);
}
/**
Test that the subject table of INSERT/UPDATE/DELETE/CREATE
or (in case of MyISAMMRG) one of its children are not used later
@@ -1308,6 +1338,25 @@ retry:
TABLE_LIST*
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag)
{
return find_table(thd, table, table_list, check_flag, NULL,
&unique_table_callback);
}
TABLE_LIST*
unique_table_in_insert_returning_subselect(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
{
return find_table(thd, table, NULL, 0, sel,
&unique_in_sel_table_callback);
}
static
TABLE_LIST*
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
uint check_flag, SELECT_LEX *sel, find_table_callback callback )
{
TABLE_LIST *dup;
@@ -1339,12 +1388,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
if (!tmp_parent)
break;
if ((dup= find_dup_table(thd, child, child->next_global, check_flag)))
if ((dup= (*callback)(thd, child, child->next_global, check_flag, sel)))
break;
}
}
else
dup= find_dup_table(thd, table, table_list, check_flag);
dup= (*callback)(thd, table, table_list, check_flag, sel);
return dup;
}
@@ -7452,6 +7501,9 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
if (!found)
continue; // No matching field
/* Restore field_2 to point to the field which was a match for field_1. */
field_2= nj_col_2->field();
/*
field_1 and field_2 have the same names. Check if they are in the USING
clause (if present), mark them as common fields, and add a new
@@ -8434,7 +8486,7 @@ bool setup_tables_and_check_access(THD *thd, Name_resolution_context *context,
if (table_list->belong_to_view && !table_list->view &&
check_single_table_access(thd, access, table_list, FALSE))
{
tables->hide_view_error(thd);
tables->replace_view_error_with_generic(thd);
DBUG_RETURN(TRUE);
}
access= want_access;
@@ -8950,14 +9002,15 @@ static bool vers_update_or_validate_fields(TABLE *table)
}
static void unwind_stored_field_offsets(const List<Item> &fields, Field *end)
static void unwind_stored_field_offsets(const List<Item> &fields, Item_field *end)
{
for (Item &item_field: fields)
for (Item &item: fields)
{
Field *f= item_field.field_for_view_update()->field;
if (f == end)
Item_field *item_field= item.field_for_view_update();
if (item_field == end)
break;
Field *f= item_field->field;
if (f->stored_in_db())
{
TABLE *table= f->table;
@@ -9001,7 +9054,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
{
List_iterator_fast<Item> f(fields),v(values);
Item *value, *fld;
Item_field *field;
Item_field *field= NULL;
Field *rfield;
TABLE *table;
bool only_unvers_fields= update && table_arg->versioned();
@@ -9019,11 +9072,8 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
while ((fld= f++))
{
if (!(field= fld->field_for_view_update()))
{
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name.str);
goto err_unwind_fields;
}
field= fld->field_for_view_update();
DBUG_ASSERT(field); // ensured by check_fields or check_view_insertability.
value=v++;
DBUG_ASSERT(value);
rfield= field->field;
@@ -9091,7 +9141,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
DBUG_RETURN(thd->is_error());
err_unwind_fields:
if (update && thd->variables.sql_mode & MODE_SIMULTANEOUS_ASSIGNMENT)
unwind_stored_field_offsets(fields, rfield);
unwind_stored_field_offsets(fields, field);
err:
DBUG_PRINT("error",("got error"));
thd->abort_on_warning= save_abort_on_warning;