1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Moving a part of st_select_lex_unit::prepare() into a new method prepare_join()

This is to simplify the logic inside st_select_lex_unit::prepare(),
to implement data type aggregation for pluggable data types.
This commit is contained in:
Alexander Barkov
2017-04-26 09:49:41 +04:00
parent 2fd635409d
commit 61a771df00
2 changed files with 73 additions and 49 deletions

View File

@ -749,6 +749,9 @@ public:
/* UNION methods */ /* UNION methods */
bool prepare(THD *thd, select_result *result, ulong additional_options); bool prepare(THD *thd, select_result *result, ulong additional_options);
bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
ulong additional_options,
bool is_union_select);
bool optimize(); bool optimize();
bool exec(); bool exec();
bool exec_recursive(); bool exec_recursive();

View File

@ -636,6 +636,59 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
} }
bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
select_result *tmp_result,
ulong additional_options,
bool is_union_select)
{
DBUG_ENTER("st_select_lex_unit::prepare_join");
bool can_skip_order_by;
sl->options|= SELECT_NO_UNLOCK;
JOIN *join= new JOIN(thd_arg, sl->item_list,
(sl->options | thd_arg->variables.option_bits |
additional_options),
tmp_result);
if (!join)
DBUG_RETURN(true);
thd_arg->lex->current_select= sl;
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
saved_error= join->prepare(sl->table_list.first,
sl->with_wild,
sl->where,
(can_skip_order_by ? 0 :
sl->order_list.elements) +
sl->group_list.elements,
can_skip_order_by ?
NULL : sl->order_list.first,
can_skip_order_by,
sl->group_list.first,
sl->having,
(is_union_select ? NULL :
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;
if (saved_error || (saved_error= thd_arg->is_fatal_error))
DBUG_RETURN(true);
/*
Remove all references from the select_lex_units to the subqueries that
are inside the ORDER BY clause.
*/
if (can_skip_order_by)
{
for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
{
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
}
}
DBUG_RETURN(false);
}
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
@ -747,15 +800,22 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
tmp_result= sel_result; tmp_result= sel_result;
sl->context.resolve_in_select_list= TRUE; sl->context.resolve_in_select_list= TRUE;
if (!is_union_select && !is_recursive)
{
if (prepare_join(thd_arg, first_sl, tmp_result, additional_options,
is_union_select))
goto err;
types= first_sl->item_list;
goto cont;
}
for (;sl; sl= sl->next_select()) for (;sl; sl= sl->next_select())
{ {
bool can_skip_order_by; if (prepare_join(thd_arg, sl, tmp_result, additional_options,
sl->options|= SELECT_NO_UNLOCK; is_union_select))
JOIN *join= new JOIN(thd_arg, sl->item_list, goto err;
(sl->options | thd_arg->variables.option_bits |
additional_options),
tmp_result);
/* /*
setup_tables_done_option should be set only for very first SELECT, setup_tables_done_option should be set only for very first SELECT,
because it protect from secont setup_tables call for select-like non because it protect from secont setup_tables call for select-like non
@ -763,53 +823,12 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT (for union it can be only INSERT ... SELECT). SELECT (for union it can be only INSERT ... SELECT).
*/ */
additional_options&= ~OPTION_SETUP_TABLES_DONE; additional_options&= ~OPTION_SETUP_TABLES_DONE;
if (!join)
goto err;
thd_arg->lex->current_select= sl;
can_skip_order_by= is_union_select && !(sl->braces && sl->explicit_limit);
saved_error= join->prepare(sl->table_list.first,
sl->with_wild,
sl->where,
(can_skip_order_by ? 0 :
sl->order_list.elements) +
sl->group_list.elements,
can_skip_order_by ?
NULL : sl->order_list.first,
can_skip_order_by,
sl->group_list.first,
sl->having,
(is_union_select ? NULL :
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;
if (saved_error || (saved_error= thd_arg->is_fatal_error))
goto err;
/*
Remove all references from the select_lex_units to the subqueries that
are inside the ORDER BY clause.
*/
if (can_skip_order_by)
{
for (ORDER *ord= (ORDER *)sl->order_list.first; ord; ord= ord->next)
{
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
}
}
/* /*
Use items list of underlaid select for derived tables to preserve Use items list of underlaid select for derived tables to preserve
information about fields lengths and exact types information about fields lengths and exact types
*/ */
if (!is_union_select && !is_recursive) if (sl == first_sl)
types= first_sl->item_list;
else if (sl == first_sl)
{ {
if (is_recursive) if (is_recursive)
{ {
@ -846,6 +865,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp; Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++)) while ((type= tp++, item_tmp= it++))
{ {
DBUG_ASSERT(item_tmp->fixed);
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp)) if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -878,6 +898,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
} }
} }
cont:
/* /*
If the query is using select_union_direct, we have postponed If the query is using select_union_direct, we have postponed
preparation of the underlying select_result until column types preparation of the underlying select_result until column types