mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge branch '10.3' into 10.4
This commit is contained in:
184
sql/sql_base.cc
184
sql/sql_base.cc
@ -7749,46 +7749,118 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
DBUG_RETURN(MY_TEST(thd->is_error()));
|
||||
}
|
||||
|
||||
/*
|
||||
make list of leaves for a single TABLE_LIST
|
||||
|
||||
SYNOPSIS
|
||||
make_leaves_for_single_table()
|
||||
thd Thread handler
|
||||
leaves List of leaf tables to be filled
|
||||
table TABLE_LIST object to process
|
||||
full_table_list Whether to include tables from mergeable derived table/view
|
||||
*/
|
||||
void make_leaves_for_single_table(THD *thd, List<TABLE_LIST> &leaves,
|
||||
TABLE_LIST *table, bool& full_table_list,
|
||||
TABLE_LIST *boundary)
|
||||
{
|
||||
if (table == boundary)
|
||||
full_table_list= !full_table_list;
|
||||
if (full_table_list && table->is_merged_derived())
|
||||
{
|
||||
SELECT_LEX *select_lex= table->get_single_select();
|
||||
/*
|
||||
It's safe to use select_lex->leaf_tables because all derived
|
||||
tables/views were already prepared and has their leaf_tables
|
||||
set properly.
|
||||
*/
|
||||
make_leaves_list(thd, leaves, select_lex->get_table_list(),
|
||||
full_table_list, boundary);
|
||||
}
|
||||
else
|
||||
{
|
||||
leaves.push_back(table, thd->mem_root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
make list of leaves of join table tree
|
||||
|
||||
SYNOPSIS
|
||||
make_leaves_list()
|
||||
list pointer to pointer on list first element
|
||||
tables table list
|
||||
full_table_list whether to include tables from mergeable derived table/view.
|
||||
we need them for checks for INSERT/UPDATE statements only.
|
||||
|
||||
RETURN pointer on pointer to next_leaf of last element
|
||||
leaves List of leaf tables to be filled
|
||||
tables Table list
|
||||
full_table_list Whether to include tables from mergeable derived table/view.
|
||||
We need them for checks for INSERT/UPDATE statements only.
|
||||
*/
|
||||
|
||||
void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
|
||||
void make_leaves_list(THD *thd, List<TABLE_LIST> &leaves, TABLE_LIST *tables,
|
||||
bool full_table_list, TABLE_LIST *boundary)
|
||||
|
||||
{
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_local)
|
||||
{
|
||||
if (table == boundary)
|
||||
full_table_list= !full_table_list;
|
||||
if (full_table_list && table->is_merged_derived())
|
||||
{
|
||||
SELECT_LEX *select_lex= table->get_single_select();
|
||||
/*
|
||||
It's safe to use select_lex->leaf_tables because all derived
|
||||
tables/views were already prepared and has their leaf_tables
|
||||
set properly.
|
||||
*/
|
||||
make_leaves_list(thd, list, select_lex->get_table_list(),
|
||||
full_table_list, boundary);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.push_back(table, thd->mem_root);
|
||||
}
|
||||
make_leaves_for_single_table(thd, leaves, table, full_table_list,
|
||||
boundary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup the map and other attributes for a single TABLE_LIST object
|
||||
|
||||
SYNOPSIS
|
||||
setup_table_attributes()
|
||||
thd Thread handler
|
||||
table_list TABLE_LIST object to process
|
||||
first_select_table First table participating in SELECT for INSERT..SELECT
|
||||
statements, NULL for other cases
|
||||
tablenr Serial number of the table in the SQL statement
|
||||
|
||||
RETURN
|
||||
false Success
|
||||
true Failure
|
||||
*/
|
||||
bool setup_table_attributes(THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST *first_select_table,
|
||||
uint &tablenr)
|
||||
{
|
||||
TABLE *table= table_list->table;
|
||||
if (table)
|
||||
table->pos_in_table_list= table_list;
|
||||
if (first_select_table && table_list->top_table() == first_select_table)
|
||||
{
|
||||
/* new counting for SELECT of INSERT ... SELECT command */
|
||||
first_select_table= 0;
|
||||
thd->lex->first_select_lex()->insert_tables= tablenr;
|
||||
tablenr= 0;
|
||||
}
|
||||
if (table_list->jtbm_subselect)
|
||||
{
|
||||
table_list->jtbm_table_no= tablenr;
|
||||
}
|
||||
else if (table)
|
||||
{
|
||||
table->pos_in_table_list= table_list;
|
||||
setup_table_map(table, table_list, tablenr);
|
||||
|
||||
if (table_list->process_index_hints(table))
|
||||
return true;
|
||||
}
|
||||
tablenr++;
|
||||
/*
|
||||
We test the max tables here as we setup_table_map() should not be called
|
||||
with tablenr >= 64
|
||||
*/
|
||||
if (tablenr > MAX_TABLES)
|
||||
{
|
||||
my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast<int>(MAX_TABLES));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
prepare tables
|
||||
|
||||
@ -7845,7 +7917,14 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
leaves.empty();
|
||||
if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED)
|
||||
{
|
||||
make_leaves_list(thd, leaves, tables, full_table_list, first_select_table);
|
||||
/*
|
||||
For INSERT ... SELECT statements we must not include the first table
|
||||
(where the data is being inserted into) in the list of leaves
|
||||
*/
|
||||
TABLE_LIST *tables_for_leaves=
|
||||
select_insert ? first_select_table : tables;
|
||||
make_leaves_list(thd, leaves, tables_for_leaves, full_table_list,
|
||||
first_select_table);
|
||||
select_lex->prep_leaf_list_state= SELECT_LEX::READY;
|
||||
select_lex->leaf_tables_exec.empty();
|
||||
}
|
||||
@ -7856,40 +7935,33 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
leaves.push_back(table_list, thd->mem_root);
|
||||
}
|
||||
|
||||
List_iterator<TABLE_LIST> ti(leaves);
|
||||
while ((table_list= ti++))
|
||||
{
|
||||
TABLE *table= table_list->table;
|
||||
if (table)
|
||||
table->pos_in_table_list= table_list;
|
||||
if (first_select_table &&
|
||||
table_list->top_table() == first_select_table)
|
||||
{
|
||||
/* new counting for SELECT of INSERT ... SELECT command */
|
||||
first_select_table= 0;
|
||||
thd->lex->first_select_lex()->insert_tables= tablenr;
|
||||
tablenr= 0;
|
||||
}
|
||||
if(table_list->jtbm_subselect)
|
||||
{
|
||||
table_list->jtbm_table_no= tablenr;
|
||||
}
|
||||
else if (table)
|
||||
{
|
||||
table->pos_in_table_list= table_list;
|
||||
setup_table_map(table, table_list, tablenr);
|
||||
|
||||
if (table_list->process_index_hints(table))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
tablenr++;
|
||||
/*
|
||||
We test the max tables here as we setup_table_map() should not be called
|
||||
with tablenr >= 64
|
||||
*/
|
||||
if (tablenr > MAX_TABLES)
|
||||
{
|
||||
my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES));
|
||||
if (setup_table_attributes(thd, table_list, first_select_table, tablenr))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (select_insert)
|
||||
{
|
||||
/*
|
||||
The table/view in which the data is inserted must not be included into
|
||||
the leaf_tables list. But we need this table/view to setup attributes
|
||||
for it. So build a temporary list of leaves and setup attributes for
|
||||
the tables included
|
||||
*/
|
||||
List<TABLE_LIST> leaves;
|
||||
TABLE_LIST *table= tables;
|
||||
|
||||
make_leaves_for_single_table(thd, leaves, table, full_table_list,
|
||||
first_select_table);
|
||||
|
||||
List_iterator<TABLE_LIST> ti(leaves);
|
||||
while ((table_list= ti++))
|
||||
{
|
||||
if (setup_table_attributes(thd, table_list, first_select_table,
|
||||
tablenr))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user