mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge of the mwl106 tree into the latest 5.3 tree.
Resolved conflicts. Adjusted some test results
This commit is contained in:
107
sql/sql_union.cc
107
sql/sql_union.cc
@ -105,6 +105,7 @@ bool select_union::flush()
|
||||
options create options
|
||||
table_alias name of the temporary table
|
||||
bit_fields_as_long convert bit fields to ulonglong
|
||||
create_table whether to physically create result table
|
||||
|
||||
DESCRIPTION
|
||||
Create a temporary table that is used to store the result of a UNION,
|
||||
@ -119,7 +120,7 @@ bool
|
||||
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||
bool is_union_distinct, ulonglong options,
|
||||
const char *alias,
|
||||
bool bit_fields_as_long)
|
||||
bool bit_fields_as_long, bool create_table)
|
||||
{
|
||||
DBUG_ASSERT(table == 0);
|
||||
tmp_table_param.init();
|
||||
@ -128,10 +129,14 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||
|
||||
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
|
||||
(ORDER*) 0, is_union_distinct, 1,
|
||||
options, HA_POS_ERROR, (char*) alias)))
|
||||
options, HA_POS_ERROR, (char*) alias,
|
||||
!create_table)))
|
||||
return TRUE;
|
||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
if (create_table)
|
||||
{
|
||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -285,6 +290,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
(is_union_select ? (ORDER*) 0 :
|
||||
(ORDER*) thd_arg->lex->proc_list.first),
|
||||
sl, this);
|
||||
|
||||
/* There are no * in the statement anymore (for PS) */
|
||||
sl->with_wild= 0;
|
||||
last_procedure= join->procedure;
|
||||
@ -347,6 +353,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
List_iterator_fast<Item> tp(types);
|
||||
Item *type;
|
||||
ulonglong create_options;
|
||||
uint save_tablenr;
|
||||
table_map save_map;
|
||||
|
||||
while ((type= tp++))
|
||||
{
|
||||
@ -399,12 +407,22 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
|
||||
|
||||
if (union_result->create_result_table(thd, &types, test(union_distinct),
|
||||
create_options, "", FALSE))
|
||||
create_options, "", FALSE, TRUE))
|
||||
goto err;
|
||||
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
||||
{
|
||||
save_tablenr= result_table_list.tablenr_exec;
|
||||
save_map= result_table_list.map_exec;
|
||||
}
|
||||
bzero((char*) &result_table_list, sizeof(result_table_list));
|
||||
result_table_list.db= (char*) "";
|
||||
result_table_list.table_name= result_table_list.alias= (char*) "union";
|
||||
result_table_list.table= table= union_result->table;
|
||||
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
||||
{
|
||||
result_table_list.tablenr_exec= save_tablenr;
|
||||
result_table_list.map_exec= save_map;
|
||||
}
|
||||
|
||||
thd_arg->lex->current_select= lex_select_save;
|
||||
if (!item_list.elements)
|
||||
@ -469,18 +487,21 @@ err:
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex_unit::exec()
|
||||
/**
|
||||
Run optimization phase.
|
||||
|
||||
@return FALSE unit successfully passed optimization phase.
|
||||
@return TRUE an error occur.
|
||||
*/
|
||||
bool st_select_lex_unit::optimize()
|
||||
{
|
||||
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
||||
SELECT_LEX *select_cursor=first_select();
|
||||
ulonglong add_rows=0;
|
||||
ha_rows examined_rows= 0;
|
||||
DBUG_ENTER("st_select_lex_unit::exec");
|
||||
DBUG_ENTER("st_select_lex_unit::optimize");
|
||||
|
||||
if (executed && !uncacheable && !describe)
|
||||
if (optimized && !uncacheable && !describe)
|
||||
DBUG_RETURN(FALSE);
|
||||
executed= 1;
|
||||
|
||||
|
||||
if (uncacheable || !item || !item->assigned() || describe)
|
||||
{
|
||||
if (item)
|
||||
@ -501,12 +522,71 @@ bool st_select_lex_unit::exec()
|
||||
}
|
||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||
{
|
||||
ha_rows records_at_start= 0;
|
||||
thd->lex->current_select= sl;
|
||||
|
||||
if (optimized)
|
||||
saved_error= sl->join->reinit();
|
||||
else
|
||||
{
|
||||
set_limit(sl);
|
||||
if (sl == global_parameters || describe)
|
||||
{
|
||||
offset_limit_cnt= 0;
|
||||
/*
|
||||
We can't use LIMIT at this stage if we are using ORDER BY for the
|
||||
whole query
|
||||
*/
|
||||
if (sl->order_list.first || describe)
|
||||
select_limit_cnt= HA_POS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
||||
we don't calculate found_rows() per union part.
|
||||
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
||||
*/
|
||||
sl->join->select_options=
|
||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||
|
||||
saved_error= sl->join->optimize();
|
||||
}
|
||||
|
||||
if (saved_error)
|
||||
{
|
||||
thd->lex->current_select= lex_select_save;
|
||||
DBUG_RETURN(saved_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
optimized= 1;
|
||||
|
||||
thd->lex->current_select= lex_select_save;
|
||||
DBUG_RETURN(saved_error);
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex_unit::exec()
|
||||
{
|
||||
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
||||
SELECT_LEX *select_cursor=first_select();
|
||||
ulonglong add_rows=0;
|
||||
ha_rows examined_rows= 0;
|
||||
DBUG_ENTER("st_select_lex_unit::exec");
|
||||
|
||||
if (executed && !uncacheable && !describe)
|
||||
DBUG_RETURN(FALSE);
|
||||
executed= 1;
|
||||
|
||||
saved_error= optimize();
|
||||
|
||||
if (uncacheable || !item || !item->assigned() || describe)
|
||||
{
|
||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||
{
|
||||
ha_rows records_at_start= 0;
|
||||
thd->lex->current_select= sl;
|
||||
|
||||
{
|
||||
set_limit(sl);
|
||||
if (sl == global_parameters || describe)
|
||||
@ -580,7 +660,6 @@ bool st_select_lex_unit::exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
optimized= 1;
|
||||
|
||||
/* Send result to 'result' */
|
||||
saved_error= TRUE;
|
||||
|
Reference in New Issue
Block a user