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

Fixes for queries containing constant scalar subselects in the WHERE clause.

For queries of the form:
SELECT col1 FROM t1 WHERE col2 = (SELECT 2);

We fix the execution plan which earlier had an empty filters
expression. For this query, we now build a SimpleFilter with a
SimpleColumn and a ConstantColumn as the LHS and the RHS operands
respectively.

For queries of the form:
SELECT ... WHERE col1 NOT IN (SELECT <const_item>);

The execution plan earlier built a SimpleFilter with an "=" as
the predicate operator of the filter. We fix this by assigning
the correct "<>" operator instead.
This commit is contained in:
Gagan Goel
2021-06-25 08:49:53 +00:00
parent 28fd12a008
commit 8d0ca55495

View File

@ -5388,6 +5388,22 @@ void castTypeArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms)
functionParms.push_back(sptp);
}
bool isSecondArgumentConstItem(Item_func* ifp)
{
return (ifp->argument_count() == 2 &&
ifp->arguments()[1]->type() == Item::CONST_ITEM);
}
// SELECT ... WHERE <col> NOT IN (SELECT <const_item>);
bool isNotFuncAndConstScalarSubSelect(Item_func* ifp, const std::string& funcName)
{
return (ifp->with_subquery() && funcName == "not" &&
ifp->argument_count() == 1 &&
ifp->arguments()[0]->type() == Item::FUNC_ITEM &&
std::string(((Item_func*)ifp->arguments()[0])->func_name()) == "=" &&
isSecondArgumentConstItem((Item_func*)ifp->arguments()[0]));
}
void gp_walk(const Item* item, void* arg)
{
gp_walk_info* gwip = reinterpret_cast<gp_walk_info*>(arg);
@ -5563,7 +5579,28 @@ void gp_walk(const Item* item, void* arg)
ifp->fix_fields(gwip->thd, reinterpret_cast<Item**>(&ifp));
}
if (ifp->with_subquery() || funcName == "<in_optimizer>")
// Special handling for queries of the form:
// SELECT ... WHERE col1 NOT IN (SELECT <const_item>);
if (isNotFuncAndConstScalarSubSelect(ifp, funcName))
{
idbassert(!gwip->ptWorkStack.empty());
ParseTree* pt = gwip->ptWorkStack.top();
SimpleFilter* sf = dynamic_cast<SimpleFilter*>(pt->data());
if (sf)
{
boost::shared_ptr<Operator> sop(new PredicateOperator("<>"));
sf->op(sop);
return;
}
}
// Do not call buildSubselectFunc() if the subquery is a const scalar
// subselect of the form:
// (SELECT <const_item>)
// As an example: SELECT col1 FROM t1 WHERE col2 = (SELECT 2);
if ((ifp->with_subquery() && !isSecondArgumentConstItem(ifp)) ||
funcName == "<in_optimizer>")
{
buildSubselectFunc(ifp, gwip);
return;