Subquery pushdown planner uses original query

With this commit, we change the input to the logical planner for
subquery pushdown. Before this commit, the planner was relying
on the query tree that is transformed by the postgresql planner.
After this commit, the planner uses the original query. The main
motivation behind this change is the simplify deparsing of
subqueries.
pull/1306/head
Onder Kalaci 2017-03-27 16:43:36 +03:00
parent f689612e68
commit 749f70d0ca
5 changed files with 22 additions and 12 deletions

View File

@ -104,28 +104,35 @@ static MultiNode * ApplyCartesianProduct(MultiNode *leftNode, MultiNode *rightNo
* Local functions forward declarations for subquery pushdown. Note that these * Local functions forward declarations for subquery pushdown. Note that these
* functions will be removed with upcoming subqery changes. * functions will be removed with upcoming subqery changes.
*/ */
static MultiNode * SubqueryPushdownMultiPlanTree(Query *queryTree, static MultiNode * SubqueryPushdownMultiPlanTree(Query *queryTree);
List *subqueryEntryList);
static void ErrorIfSubqueryJoin(Query *queryTree); static void ErrorIfSubqueryJoin(Query *queryTree);
static MultiTable * MultiSubqueryPushdownTable(RangeTblEntry *subqueryRangeTableEntry); static MultiTable * MultiSubqueryPushdownTable(RangeTblEntry *subqueryRangeTableEntry);
/* /*
* MultiLogicalPlanCreate takes in a parsed query tree, uses helper functions to * MultiLogicalPlanCreate takes in both the original query and its corresponding modified
* create logical plan and adds a root node to top of it. * query tree yield by the standard planner. It uses helper functions to create logical
* plan and adds a root node to top of it. The original query is only used for subquery
* pushdown planning.
*/ */
MultiTreeRoot * MultiTreeRoot *
MultiLogicalPlanCreate(Query *queryTree) MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree)
{ {
MultiNode *multiQueryNode = NULL; MultiNode *multiQueryNode = NULL;
MultiTreeRoot *rootNode = NULL; MultiTreeRoot *rootNode = NULL;
List *subqueryEntryList = NULL;
List *subqueryEntryList = SubqueryEntryList(queryTree); /*
* We check the existence of subqueries in the modified query given that
* if postgres already flattened the subqueries, MultiPlanTree() can plan
* corresponding distributed plan.
*/
subqueryEntryList = SubqueryEntryList(queryTree);
if (subqueryEntryList != NIL) if (subqueryEntryList != NIL)
{ {
if (SubqueryPushdown) if (SubqueryPushdown)
{ {
multiQueryNode = SubqueryPushdownMultiPlanTree(queryTree, subqueryEntryList); multiQueryNode = SubqueryPushdownMultiPlanTree(originalQuery);
} }
else else
{ {
@ -1982,7 +1989,7 @@ ApplyCartesianProduct(MultiNode *leftNode, MultiNode *rightNode,
* from other parts of code although it causes some code duplication. * from other parts of code although it causes some code duplication.
*/ */
static MultiNode * static MultiNode *
SubqueryPushdownMultiPlanTree(Query *queryTree, List *subqueryEntryList) SubqueryPushdownMultiPlanTree(Query *queryTree)
{ {
List *targetEntryList = queryTree->targetList; List *targetEntryList = queryTree->targetList;
List *qualifierList = NIL; List *qualifierList = NIL;
@ -1997,6 +2004,7 @@ SubqueryPushdownMultiPlanTree(Query *queryTree, List *subqueryEntryList)
MultiExtendedOp *extendedOpNode = NULL; MultiExtendedOp *extendedOpNode = NULL;
MultiNode *currentTopNode = NULL; MultiNode *currentTopNode = NULL;
RangeTblEntry *subqueryRangeTableEntry = NULL; RangeTblEntry *subqueryRangeTableEntry = NULL;
List *subqueryEntryList = SubqueryEntryList(queryTree);
/* verify we can perform distributed planning on this query */ /* verify we can perform distributed planning on this query */
ErrorIfQueryNotSupported(queryTree); ErrorIfQueryNotSupported(queryTree);

View File

@ -311,7 +311,7 @@ CreateDistributedPlan(PlannedStmt *localPlan, Query *originalQuery, Query *query
if ((!distributedPlan || distributedPlan->planningError) && !hasUnresolvedParams) if ((!distributedPlan || distributedPlan->planningError) && !hasUnresolvedParams)
{ {
/* Create and optimize logical plan */ /* Create and optimize logical plan */
MultiTreeRoot *logicalPlan = MultiLogicalPlanCreate(query); MultiTreeRoot *logicalPlan = MultiLogicalPlanCreate(originalQuery, query);
MultiLogicalPlanOptimize(logicalPlan, plannerRestrictionContext); MultiLogicalPlanOptimize(logicalPlan, plannerRestrictionContext);
/* /*

View File

@ -180,7 +180,7 @@ extern bool SubqueryPushdown;
/* Function declarations for building logical plans */ /* Function declarations for building logical plans */
extern MultiTreeRoot * MultiLogicalPlanCreate(Query *queryTree); extern MultiTreeRoot * MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree);
extern bool NeedsDistributedPlanning(Query *queryTree); extern bool NeedsDistributedPlanning(Query *queryTree);
extern MultiNode * ParentNode(MultiNode *multiNode); extern MultiNode * ParentNode(MultiNode *multiNode);
extern MultiNode * ChildNode(MultiUnaryNode *multiNode); extern MultiNode * ChildNode(MultiUnaryNode *multiNode);

View File

@ -178,7 +178,8 @@ SELECT count(*) FROM
(SELECT l_orderkey FROM lineitem_subquery) UNION ALL (SELECT l_orderkey FROM lineitem_subquery) UNION ALL
(SELECT 1::bigint) (SELECT 1::bigint)
) b; ) b;
ERROR: could not run distributed query with complex table expressions ERROR: cannot push down this subquery
DETAIL: Union All clauses are currently unsupported
--- ---
-- TEMPORARLY DISABLE UNIONS WITHOUT JOINS -- TEMPORARLY DISABLE UNIONS WITHOUT JOINS
--- ---

View File

@ -178,7 +178,8 @@ SELECT count(*) FROM
(SELECT l_orderkey FROM lineitem_subquery) UNION ALL (SELECT l_orderkey FROM lineitem_subquery) UNION ALL
(SELECT 1::bigint) (SELECT 1::bigint)
) b; ) b;
ERROR: could not run distributed query with complex table expressions ERROR: cannot push down this subquery
DETAIL: Union All clauses are currently unsupported
--- ---
-- TEMPORARLY DISABLE UNIONS WITHOUT JOINS -- TEMPORARLY DISABLE UNIONS WITHOUT JOINS
--- ---