Skip to content

Commit

Permalink
Moving a part of st_select_lex_unit::prepare() into a new method prep…
Browse files Browse the repository at this point in the history
…are_join()

This is to simplify the logic inside st_select_lex_unit::prepare(),
to implement data type aggregation for pluggable data types.
  • Loading branch information
Alexander Barkov committed Apr 26, 2017
1 parent 2fd6354 commit 61a771d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 49 deletions.
3 changes: 3 additions & 0 deletions sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,9 @@ class st_select_lex_unit: public st_select_lex_node {

/* UNION methods */
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 exec();
bool exec_recursive();
Expand Down
119 changes: 70 additions & 49 deletions sql/sql_union.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -747,69 +800,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
tmp_result= sel_result;

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())
{
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 (prepare_join(thd_arg, sl, tmp_result, additional_options,
is_union_select))
goto err;

/*
setup_tables_done_option should be set only for very first SELECT,
because it protect from secont setup_tables call for select-like non
select commands (DELETE/INSERT/...) and they use only very first
SELECT (for union it can be only INSERT ... SELECT).
*/
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
information about fields lengths and exact types
*/
if (!is_union_select && !is_recursive)
types= first_sl->item_list;
else if (sl == first_sl)
if (sl == first_sl)
{
if (is_recursive)
{
Expand Down Expand Up @@ -846,6 +865,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++))
{
DBUG_ASSERT(item_tmp->fixed);
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
DBUG_RETURN(TRUE);
}
Expand Down Expand Up @@ -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
preparation of the underlying select_result until column types
Expand Down

0 comments on commit 61a771d

Please sign in to comment.