提交 1f91b092 编写于 作者: H Heikki Linnakangas

Move stripping of subqueries to the end of planning.

Seems more straightforward. Firstly, modifying a PlannedStmt at execution
is dubious, if the PlannedStmt is reused for executing the same query
again. Secondly, if the original Query objects are indeed not needed
after planning, we can save a little bit of memory, and avoid the overhead
of stripping the plan on every execution. This also makes any breakage
more obvious, if it turns out that the Query is actually still needed
at execution for some reason, as that issue would then show up on the
first execution already, and not only on reuse of a PlannedStmt.

Per Kenan Yao's observation that stripPlanBeforeDispatch() also scribbles
on the PlannedStmt.
上级 4f4f10fc
......@@ -2875,10 +2875,15 @@ remove_subquery_in_RTEs(Node *node)
if (RTE_SUBQUERY == rte->rtekind && NULL != rte->subquery)
{
/*
* replace subquery with a dummy subquery
*/
rte->subquery = makeNode(Query);
/*
* Replace subquery with a dummy subquery.
*
* XXX: We could save a lot more memory by deep-freeing the many
* fields in the Query too. But I'm not sure which of them might
* be shared by other objects in the tree.
*/
pfree(rte->subquery);
rte->subquery = makeNode(Query);
}
return;
......
......@@ -84,8 +84,6 @@ typedef struct DispatchCommandQueryParms
int primary_gang_id;
} DispatchCommandQueryParms;
static void stripPlanBeforeDispatch(PlannedStmt *plan);
static void
CdbDispatchUtilityStatement_Internal(struct Node *stmt,
bool needTwoPhase,
......@@ -285,8 +283,6 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc,
verify_shared_snapshot_ready();
}
stripPlanBeforeDispatch(queryDesc->plannedstmt);
/*
* serialized plan tree. Note that we're called for a single
* slice tree (corresponding to an initPlan or the main plan), so the
......@@ -781,16 +777,6 @@ CdbDispatchUtilityStatement_NoTwoPhase(struct Node *stmt,
"CdbDispatchUtilityStatement_NoTwoPhase");
}
/*
* Remove subquery field in RTE's with subquery kind. This is an optimization used
* to reduce plan size before serialization for dispatching.
*/
static void
stripPlanBeforeDispatch(PlannedStmt *plan)
{
remove_subquery_in_RTEs((Node *) plan->rtable);
}
/*
* Initialize CdbDispatcherState using DispatchCommandQueryParms
*
......
......@@ -192,6 +192,12 @@ static void postprocess_plan(PlannedStmt *plan)
globNew->share.nextPlanId = 0;
globNew->subplans = plan->subplans;
(void) apply_shareinput_xslice(plan->planTree, globNew);
/*
* To save on memory, and on the network bandwidth when the plan is dispatched
* QEs, strip all subquery RTEs of the original Query objects.
*/
remove_subquery_in_RTEs((Node *) plan->rtable);
}
#endif
......@@ -462,7 +468,12 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
top_plan = zap_trivial_result(root, top_plan);
/*
* To save on memory, and on the network bandwidth when the plan is dispatched
* QEs, strip all subquery RTEs of the original Query objects.
*/
remove_subquery_in_RTEs((Node *) glob->finalrtable);
/* build the PlannedStmt result */
result = makeNode(PlannedStmt);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册