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
Merge pull request #1449 from tntnatbry/MCOL-4282
MCOL-4282 Enable Select Handler for Prepared Statements
This commit is contained in:
@ -6369,8 +6369,13 @@ int processWhere(SELECT_LEX &select_lex,
|
|||||||
Item_cond* icp = 0;
|
Item_cond* icp = 0;
|
||||||
bool isUpdateDelete = false;
|
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);
|
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 icp is null, try to find the where clause other where
|
||||||
if (!join && gwi.thd->lex->derived_tables)
|
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:
|
* 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:
|
* 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:
|
* RETURN:
|
||||||
* bool to to indicate predicate injection failures.
|
* bool to indicate predicate injection failures.
|
||||||
***********************************************************/
|
***********************************************************/
|
||||||
bool in_subselect_rewrite(SELECT_LEX *select_lex)
|
bool in_subselect_rewrite(SELECT_LEX *select_lex)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
TABLE_LIST *tbl;
|
TABLE_LIST *tbl;
|
||||||
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
|
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
|
||||||
while (!result && (tbl= li++))
|
|
||||||
|
while (!result && (tbl = li++))
|
||||||
{
|
{
|
||||||
if (tbl->is_view_or_derived())
|
if (tbl->is_view_or_derived())
|
||||||
{
|
{
|
||||||
SELECT_LEX *dsl = tbl->derived->first_select();
|
SELECT_LEX_UNIT *unit= tbl->get_unit();
|
||||||
result = in_subselect_rewrite(dsl);
|
|
||||||
|
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;
|
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"
|
#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);
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -476,6 +476,10 @@ create_columnstore_derived_handler(THD* thd, TABLE_LIST *derived)
|
|||||||
return handler;
|
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_UNIT *unit= derived->derived;
|
||||||
SELECT_LEX *sl= unit->first_select();
|
SELECT_LEX *sl= unit->first_select();
|
||||||
|
|
||||||
@ -748,11 +752,15 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
|
|||||||
return handler;
|
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
|
// Disable processing of select_result_interceptor classes
|
||||||
// which intercept and transform result set rows. E.g.:
|
// which intercept and transform result set rows. E.g.:
|
||||||
// select a,b into @a1, @a2 from t1;
|
// select a,b into @a1, @a2 from t1;
|
||||||
if (((thd->lex)->result &&
|
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;
|
return handler;
|
||||||
}
|
}
|
||||||
@ -800,8 +808,34 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
|
|||||||
COND *conds = nullptr;
|
COND *conds = nullptr;
|
||||||
if (!unsupported_feature)
|
if (!unsupported_feature)
|
||||||
{
|
{
|
||||||
conds= simplify_joins_mcs(join, select_lex->join_list,
|
SELECT_LEX *sel= select_lex;
|
||||||
join->conds, TRUE, FALSE);
|
// 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)
|
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.
|
// We shouldn't raise error now so set an error to raise it later in init_SH.
|
||||||
handler->rewrite_error= unsupported_feature;
|
handler->rewrite_error= unsupported_feature;
|
||||||
|
|
||||||
// Return SH even if init fails b/c CS changed SELECT_LEX structures
|
// Return SH even if init fails b/c CS changed SELECT_LEX structures
|
||||||
// with simplify_joins_mcs()
|
// with simplify_joins_mcs()
|
||||||
return handler;
|
return handler;
|
||||||
|
Reference in New Issue
Block a user