1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

Merge pull request #1449 from tntnatbry/MCOL-4282

MCOL-4282 Enable Select Handler for Prepared Statements
This commit is contained in:
Roman Nozdrin
2020-09-14 11:07:42 +03:00
committed by GitHub
4 changed files with 114 additions and 14 deletions

View File

@ -6369,8 +6369,13 @@ int processWhere(SELECT_LEX &select_lex,
Item_cond* icp = 0;
bool isUpdateDelete = false;
if (join != 0)
// Flag to indicate if this is a prepared statement
bool isPS = gwi.thd->stmt_arena && gwi.thd->stmt_arena->is_stmt_execute();
if (join != 0 && !isPS)
icp = reinterpret_cast<Item_cond*>(join->conds);
else if (isPS && select_lex.prep_where)
icp = (Item_cond*)(select_lex.prep_where);
// if icp is null, try to find the where clause other where
if (!join && gwi.thd->lex->derived_tables)

View File

@ -299,26 +299,61 @@ void in_subselect_rewrite_walk(const Item* item_arg, void* arg)
}
}
/*@brief in_subselect_rewrite - Rewrites Item_in_subselect*/
/* @brief opt_flag_unset_PS() - Unsets first_cond_optimization */
/************************************************************
* DESCRIPTION:
* It traverses TABLE_LISTs running in_subselect_rewrite_walk
* This function traverses derived tables to 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 - SELECT_LEX* that describes the query.
***********************************************************/
void opt_flag_unset_PS(SELECT_LEX *select_lex)
{
TABLE_LIST *tbl;
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
while ((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())
opt_flag_unset_PS(sl);
}
}
if (select_lex->first_cond_optimization)
{
select_lex->first_cond_optimization= false;
}
}
/* @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 to indicate predicate injection failures.
* 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++))
while (!result && (tbl = li++))
{
if (tbl->is_view_or_derived())
{
SELECT_LEX *dsl = tbl->derived->first_select();
result = in_subselect_rewrite(dsl);
SELECT_LEX_UNIT *unit= tbl->get_unit();
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
result = in_subselect_rewrite(sl);
}
}
@ -330,3 +365,27 @@ bool in_subselect_rewrite(SELECT_LEX *select_lex)
return result;
}
uint build_bitmap_for_nested_joins_mcs(List<TABLE_LIST> *join_list,
uint first_unused)
{
List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table;
DBUG_ENTER("build_bitmap_for_nested_joins_mcs");
while ((table= li++))
{
NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join))
{
if (nested_join->n_tables != 1)
{
/* Don't assign bits to sj-nests */
if (table->on_expr)
nested_join->nj_map= (nested_join_map) 1 << first_unused++;
first_unused= build_bitmap_for_nested_joins_mcs(&nested_join->join_list,
first_unused);
}
}
}
DBUG_RETURN(first_unused);
}

View File

@ -20,8 +20,11 @@
#include "idb_mysql.h"
COND *simplify_joins_mcs(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top, bool in_sj);
bool in_subselect_rewrite(SELECT_LEX *select_lex);
void opt_flag_unset_PS(SELECT_LEX *select_lex);
COND *simplify_joins_mcs(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top, bool in_sj);
uint build_bitmap_for_nested_joins_mcs(List<TABLE_LIST> *join_list,
uint first_unused);
#endif

View File

@ -476,6 +476,10 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived)
return handler;
}
// Disable derived handler for prepared statements
if (thd->stmt_arena && thd->stmt_arena->is_stmt_execute())
return handler;
SELECT_LEX_UNIT *unit= derived->derived;
SELECT_LEX *sl= unit->first_select();
@ -748,11 +752,15 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
return handler;
}
// Flag to indicate if this is a prepared statement
bool isPS = thd->stmt_arena && thd->stmt_arena->is_stmt_execute();
// Disable processing of select_result_interceptor classes
// which intercept and transform result set rows. E.g.:
// select a,b into @a1, @a2 from t1;
if (((thd->lex)->result &&
!((select_dumpvar *)(thd->lex)->result)->var_list.is_empty()))
!((select_dumpvar *)(thd->lex)->result)->var_list.is_empty()) &&
(!isPS))
{
return handler;
}
@ -800,8 +808,34 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
COND *conds = nullptr;
if (!unsupported_feature)
{
conds= simplify_joins_mcs(join, select_lex->join_list,
join->conds, TRUE, FALSE);
SELECT_LEX *sel= select_lex;
// Rewrite once for PS
// Refer to JOIN::optimize_inner() in sql/sql_select.cc
// for details on the optimizations performed in this block.
if (sel->first_cond_optimization)
{
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
sel->first_cond_optimization= false;
conds= simplify_joins_mcs(join, select_lex->join_list,
join->conds, TRUE, FALSE);
build_bitmap_for_nested_joins_mcs(select_lex->join_list, 0);
sel->where= conds;
if (isPS)
sel->prep_where= conds;
select_lex->update_used_tables();
if (arena)
thd->restore_active_arena(arena, &backup);
// Unset SL::first_cond_optimization
opt_flag_unset_PS(sel);
}
}
if (!unsupported_feature && conds)
@ -825,7 +859,6 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
// We shouldn't raise error now so set an error to raise it later in init_SH.
handler->rewrite_error= unsupported_feature;
// Return SH even if init fails b/c CS changed SELECT_LEX structures
// with simplify_joins_mcs()
return handler;