1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

MCOL-4023 Pushdown WHERE conditions for UPDATE/DELETE.

For certain queries, such as:
  update cs1 set i = 41 where i = 42 or (i is null and 42 is null);
the SELECT_LEX.where does not contain the required where conditions.
Server sends the where conditions in the call to cond_push(), so
we are storing them in a handler data member, condStack, and later
push them down to getSelectPlan() for UPDATES/DELETEs.
This commit is contained in:
Gagan Goel
2020-05-29 22:30:34 -04:00
committed by Patrick LeBlanc
parent a8f5d353bd
commit 01ff2652a6
6 changed files with 98 additions and 22 deletions

View File

@ -6333,10 +6333,12 @@ int processFrom(bool &isUnion,
int processWhere(SELECT_LEX &select_lex,
gp_walk_info &gwi,
SCSEP &csep,
List<Item> &on_expr_list)
List<Item> &on_expr_list,
const std::vector<COND*>& condStack)
{
JOIN* join = select_lex.join;
Item_cond* icp = 0;
bool isUpdateDelete = false;
if (join != 0)
icp = reinterpret_cast<Item_cond*>(join->conds);
@ -6354,7 +6356,7 @@ int processWhere(SELECT_LEX &select_lex,
((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ||
((gwi.thd->lex)->sql_command == SQLCOM_DELETE_MULTI )))
{
icp = reinterpret_cast<Item_cond*>(select_lex.where);
isUpdateDelete = true;
}
if (icp)
@ -6393,6 +6395,51 @@ int processWhere(SELECT_LEX &select_lex,
return ER_INTERNAL_ERROR;
}
}
else if (isUpdateDelete)
{
// MCOL-4023 For updates/deletes, we iterate over the pushed down condStack
if (!condStack.empty())
{
std::vector<COND*>::const_iterator condStackIter = condStack.begin();
while (condStackIter != condStack.end())
{
COND* cond = *condStackIter++;
cond->traverse_cond(gp_walk, &gwi, Item::POSTFIX);
if (gwi.fatalParseError)
{
if (gwi.thd->derived_tables_processing)
{
gwi.cs_vtable_is_update_with_derive = true;
return -1;
}
setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi);
return ER_INTERNAL_ERROR;
}
}
}
// if condStack is empty(), check the select_lex for where conditions
// as a last resort
else if ((icp = reinterpret_cast<Item_cond*>(select_lex.where)) != 0)
{
icp->traverse_cond(gp_walk, &gwi, Item::POSTFIX);
if (gwi.fatalParseError)
{
if (gwi.thd->derived_tables_processing)
{
gwi.cs_vtable_is_update_with_derive = true;
return -1;
}
setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi);
return ER_INTERNAL_ERROR;
}
}
}
else if (join && join->zero_result_cause)
{
gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM));
@ -6688,7 +6735,8 @@ int processLimitAndOffset(
int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
SCSEP& csep,
bool isUnion,
bool isSelectHandlerTop)
bool isSelectHandlerTop,
const std::vector<COND*>& condStack)
{
#ifdef DEBUG_WALK_COND
cerr << "getSelectPlan()" << endl;
@ -6724,7 +6772,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
bool unionSel = (!isUnion && select_lex.master_unit()->is_unit_op()) ? true : false;
gwi.clauseType = WHERE;
if ((rc = processWhere(select_lex, gwi, csep, on_expr_list)))
if ((rc = processWhere(select_lex, gwi, csep, on_expr_list, condStack)))
{
return rc;
}