You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-4282 Enable Select Handler for Prepared Statements
This patch enables select handler for executing prepared statements. Most importantly, we are now activating a persistent arena which will allocate any new items in a permanent MEMROOT for prepared statements and stored procedures. Refer to JOIN::optimize_inner() for details. In processWhere(), we now use SELECT_LEX::prep_where in case we are executing a prepared statement, as this is where the saved WHERE clause is stored for prepared statement processing. In addition, we also disable derived handler for prepared statements.
This commit is contained in:
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user