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:
116
sql/sql_base.cc
116
sql/sql_base.cc
@@ -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, ¶m))
|
||||
{
|
||||
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;
|
||||
|
Reference in New Issue
Block a user