You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-10 01:22:48 +03:00
This feature allows a query execution to fallback to the server, in case query execution using the select_handler (SH) fails. In case of fallback, a warning message containing the original reason for query failure using SH is generated. To accomplish this task, SH execution is moved to an earlier step when we create the SH in create_columnstore_select_handler(), instead of the previous call to SH execution in ha_columnstore_select_handler::init_scan(). This requires some pre-requisite steps that occur in the server in JOIN::optimize() and JOIN::exec() to be performed before starting SH execution. In addition, missing test cases from MCOL-424 are also added to the MTR suite, and the corresponding fix using disable_indices_for_CEJ() is reverted back since the original fix now appears to be redundant.
156 lines
5.1 KiB
C++
156 lines
5.1 KiB
C++
/* Copyright (C) 2019-20 MariaDB Corporation
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2 of
|
|
the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
#include <typeinfo>
|
|
|
|
#include "ha_mcs_opt_rewrites.h"
|
|
|
|
/*@brief in_subselect_rewrite_walk - Rewrites Item_in_subselect*/
|
|
/************************************************************
|
|
* DESCRIPTION:
|
|
* It traverses filter predicates searching for
|
|
* Item_in_subselect and rewrites it adding equi-join predicate
|
|
* to finalise IN_2_EXISTS rewrite.
|
|
* PARAMETERS:
|
|
* item_arg - Item to check.
|
|
* arg - bool to early return if predicate injection fails.
|
|
* RETURN:
|
|
***********************************************************/
|
|
void in_subselect_rewrite_walk(const Item* item_arg, void* arg)
|
|
{
|
|
bool* result= reinterpret_cast<bool*>(arg);
|
|
if (*result) return;
|
|
|
|
Item* item= const_cast<Item*>(item_arg);
|
|
|
|
JOIN* join= nullptr;
|
|
if (typeid(*item) == typeid(Item_in_subselect))
|
|
{
|
|
Item_in_subselect* sub= reinterpret_cast<Item_in_subselect*>(item);
|
|
// MCS 1.4.3 doesn't support IN + subquery with UNION so
|
|
// we safe to take this JOIN.
|
|
join= sub->unit->first_select()->join;
|
|
// Inject equi-JOIN predicates if needed.
|
|
*result= sub->create_in_to_exists_cond(join);
|
|
*result= (*result) ? *result :
|
|
sub->inject_in_to_exists_cond(join);
|
|
sub->unit->first_select()->prep_where=
|
|
join->conds ? join->conds->copy_andor_structure(current_thd) : 0;
|
|
}
|
|
else if (typeid(*item) == typeid(Item_singlerow_subselect))
|
|
{
|
|
Item_singlerow_subselect* sub=
|
|
reinterpret_cast<Item_singlerow_subselect*>(item);
|
|
// MCS 1.4.3 doesn't support IN + subquery with UNION so
|
|
// we safe to take this JOIN.
|
|
join= sub->unit->first_select()->join;
|
|
}
|
|
else
|
|
{
|
|
// Exit for any but dedicated Items.
|
|
return;
|
|
}
|
|
|
|
// Walk recursively to process nested IN ops.
|
|
if (join->conds)
|
|
{
|
|
join->conds->traverse_cond(in_subselect_rewrite_walk,
|
|
arg, Item::POSTFIX);
|
|
}
|
|
}
|
|
|
|
// Sets SELECT_LEX::first_cond_optimization
|
|
void first_cond_optimization_flag_set(SELECT_LEX* select_lex)
|
|
{
|
|
select_lex->first_cond_optimization = true;
|
|
}
|
|
|
|
// Unsets SELECT_LEX::first_cond_optimization
|
|
void first_cond_optimization_flag_unset(SELECT_LEX* select_lex)
|
|
{
|
|
select_lex->first_cond_optimization = false;
|
|
}
|
|
|
|
/* @brief first_cond_optimization_flag_toggle() - Sets/Unsets first_cond_optimization */
|
|
/************************************************************
|
|
* DESCRIPTION:
|
|
* This function traverses SELECT_LEX::table_list recursively
|
|
* to set/unset SELECT_LEX::first_cond_optimization: a marker
|
|
* to control optimizations executing PS. If set it allows to
|
|
* apply optimizations. If unset, it disables optimizations.
|
|
* PARAMETERS:
|
|
* select_lex - SELECT_LEX* that describes the query.
|
|
* func - Pointer to a function which either sets/unsets
|
|
* SELECT_LEX::first_cond_optimization
|
|
***********************************************************/
|
|
void first_cond_optimization_flag_toggle(SELECT_LEX *select_lex, void (*func)(SELECT_LEX*))
|
|
{
|
|
for (TABLE_LIST *tl= select_lex->get_table_list(); tl; tl= tl->next_local)
|
|
{
|
|
if (tl->is_view_or_derived())
|
|
{
|
|
SELECT_LEX_UNIT *unit= tl->get_unit();
|
|
|
|
if (unit)
|
|
{
|
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
|
{
|
|
first_cond_optimization_flag_toggle(sl, func);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
(*func)(select_lex);
|
|
}
|
|
|
|
|
|
/* @brief in_subselect_rewrite - Rewrites Item_in_subselect */
|
|
/************************************************************
|
|
* DESCRIPTION:
|
|
* This function traverses TABLE_LISTs running in_subselect_rewrite_walk
|
|
* PARAMETERS:
|
|
* select_lex - SELECT_LEX* that describes the query.
|
|
* RETURN:
|
|
* bool to indicate predicate injection failures.
|
|
***********************************************************/
|
|
bool in_subselect_rewrite(SELECT_LEX *select_lex)
|
|
{
|
|
bool result = false;
|
|
TABLE_LIST *tbl;
|
|
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
|
|
|
|
while (!result && (tbl = li++))
|
|
{
|
|
if (tbl->is_view_or_derived())
|
|
{
|
|
SELECT_LEX_UNIT *unit= tbl->get_unit();
|
|
|
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
|
result = in_subselect_rewrite(sl);
|
|
}
|
|
}
|
|
|
|
if (select_lex->join && select_lex->join->conds)
|
|
{
|
|
select_lex->join->conds->traverse_cond(in_subselect_rewrite_walk, &result,
|
|
Item::POSTFIX);
|
|
}
|
|
|
|
return result;
|
|
}
|