1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä
2022-07-27 17:17:24 +03:00
278 changed files with 17690 additions and 7421 deletions

View File

@ -7659,6 +7659,39 @@ 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);
}
}
/*
Perform checks like all given fields exists, if exists fill struct with
@ -7685,40 +7718,79 @@ int setup_returning_fields(THD* thd, TABLE_LIST* table_list)
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
@ -7775,7 +7847,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();
}
@ -7786,40 +7865,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);
}
}
}