You've already forked mariadb-columnstore-engine
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:
committed by
Patrick LeBlanc
parent
a8f5d353bd
commit
01ff2652a6
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user