diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp
index 9cd882762..fef4f9691 100755
--- a/dbcon/mysql/ha_mcs_execplan.cpp
+++ b/dbcon/mysql/ha_mcs_execplan.cpp
@@ -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
NOT IN (SELECT );
+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(arg);
@@ -5563,7 +5579,28 @@ void gp_walk(const Item* item, void* arg)
ifp->fix_fields(gwip->thd, reinterpret_cast- (&ifp));
}
- if (ifp->with_subquery() || funcName == "")
+ // Special handling for queries of the form:
+ // SELECT ... WHERE col1 NOT IN (SELECT );
+ if (isNotFuncAndConstScalarSubSelect(ifp, funcName))
+ {
+ idbassert(!gwip->ptWorkStack.empty());
+ ParseTree* pt = gwip->ptWorkStack.top();
+ SimpleFilter* sf = dynamic_cast(pt->data());
+
+ if (sf)
+ {
+ boost::shared_ptr sop(new PredicateOperator("<>"));
+ sf->op(sop);
+ return;
+ }
+ }
+
+ // Do not call buildSubselectFunc() if the subquery is a const scalar
+ // subselect of the form:
+ // (SELECT )
+ // As an example: SELECT col1 FROM t1 WHERE col2 = (SELECT 2);
+ if ((ifp->with_subquery() && !isSecondArgumentConstItem(ifp)) ||
+ funcName == "")
{
buildSubselectFunc(ifp, gwip);
return;