diff --git a/src/backend/distributed/planner/multi_explain.c b/src/backend/distributed/planner/multi_explain.c index 0e3e90b33..fd4f59cef 100644 --- a/src/backend/distributed/planner/multi_explain.c +++ b/src/backend/distributed/planner/multi_explain.c @@ -52,8 +52,6 @@ /* Config variables that enable printing distributed query plans */ -bool ExplainMultiLogicalPlan = false; -bool ExplainMultiPhysicalPlan = false; bool ExplainDistributedQueries = true; bool ExplainAllTasks = false; @@ -79,6 +77,9 @@ static void ExplainTask(Task *task, int placementIndex, List *explainOutputList, static void ExplainTaskPlacement(ShardPlacement *taskPlacement, List *explainOutputList, ExplainState *es); static StringInfo BuildRemoteExplainQuery(char *queryString, ExplainState *es); +static void MultiExplainOnePlan(PlannedStmt *plan, IntoClause *into, + ExplainState *es, const char *queryString, + ParamListInfo params, const instr_time *planDuration); /* Static Explain functions copied from explain.c */ static void ExplainOpenGroup(const char *objtype, const char *labelname, @@ -100,17 +101,10 @@ void MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params) { - MultiPlan *multiPlan = NULL; - CmdType commandType = CMD_UNKNOWN; - PlannedStmt *initialPlan = NULL; - Job *workerJob = NULL; - bool routerExecutablePlan = false; instr_time planStart; instr_time planDuration; - Query *originalQuery = NULL; - RelationRestrictionContext *restrictionContext = NULL; - bool localQuery = !NeedsDistributedPlanning(query); int cursorOptions = 0; + PlannedStmt *plan = NULL; #if PG_VERSION_NUM >= 90600 @@ -124,85 +118,54 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es, } #endif - /* handle local queries in the same way as ExplainOneQuery */ - if (localQuery) - { - PlannedStmt *plan = NULL; - - INSTR_TIME_SET_CURRENT(planStart); - - /* plan the query */ - plan = pg_plan_query(query, cursorOptions, params); - - INSTR_TIME_SET_CURRENT(planDuration); - INSTR_TIME_SUBTRACT(planDuration, planStart); - - /* run it (if needed) and produce output */ - ExplainOnePlan(plan, into, es, queryString, params, &planDuration); - - return; - } - - /* - * standard_planner scribbles on it's input, but for deparsing we need the - * unmodified form. So copy once we're sure it's a distributed query. - */ - originalQuery = copyObject(query); - - /* measure the full planning time to display in EXPLAIN ANALYZE */ + /* plan query, just like ExplainOneQuery does */ INSTR_TIME_SET_CURRENT(planStart); - restrictionContext = CreateAndPushRestrictionContext(); - - PG_TRY(); - { - /* call standard planner to modify the query structure before multi planning */ - initialPlan = standard_planner(query, cursorOptions, params); - - commandType = initialPlan->commandType; - if (commandType == CMD_INSERT || commandType == CMD_UPDATE || - commandType == CMD_DELETE) - { - if (es->analyze) - { - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Using ANALYZE for INSERT/UPDATE/DELETE on " - "distributed tables is not supported."))); - } - } - - multiPlan = CreatePhysicalPlan(originalQuery, query, restrictionContext); - } - PG_CATCH(); - { - PopRestrictionContext(); - PG_RE_THROW(); - } - PG_END_TRY(); - - PopRestrictionContext(); + /* plan the query */ + plan = pg_plan_query(query, cursorOptions, params); INSTR_TIME_SET_CURRENT(planDuration); INSTR_TIME_SUBTRACT(planDuration, planStart); - if (ExplainMultiLogicalPlan) + /* if not a distributed query, use plain explain infrastructure */ + if (!HasCitusToplevelNode(plan)) { - MultiTreeRoot *multiTree = MultiLogicalPlanCreate(query); - char *logicalPlanString = CitusNodeToString(multiTree); - char *formattedPlanString = pretty_format_node_dump(logicalPlanString); + /* run it (if needed) and produce output */ + ExplainOnePlan(plan, into, es, queryString, params, &planDuration); + } + else + { + MultiExplainOnePlan(plan, into, es, queryString, params, &planDuration); + } +} - appendStringInfo(es->str, "logical plan:\n"); - appendStringInfo(es->str, "%s\n", formattedPlanString); + +/* + * MultiExplainOnePlan explains the plan for an individual distributed query. + */ +static void +MultiExplainOnePlan(PlannedStmt *plan, IntoClause *into, + ExplainState *es, const char *queryString, + ParamListInfo params, const instr_time *planDuration) +{ + MultiPlan *multiPlan = NULL; + CmdType commandType = CMD_UNKNOWN; + Job *workerJob = NULL; + bool routerExecutablePlan = false; + + commandType = plan->commandType; + if (commandType == CMD_INSERT || commandType == CMD_UPDATE || + commandType == CMD_DELETE) + { + if (es->analyze) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("Using ANALYZE for INSERT/UPDATE/DELETE on " + "distributed tables is not supported."))); + } } - if (ExplainMultiPhysicalPlan) - { - char *physicalPlanString = CitusNodeToString(multiPlan); - char *formattedPlanString = pretty_format_node_dump(physicalPlanString); - - appendStringInfo(es->str, "physical plan:\n"); - appendStringInfo(es->str, "%s\n", formattedPlanString); - } + multiPlan = GetMultiPlan(plan); if (!ExplainDistributedQueries) { @@ -268,8 +231,6 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es, if (!routerExecutablePlan) { - PlannedStmt *masterPlan = MultiQueryContainerNode(initialPlan, multiPlan); - if (es->format == EXPLAIN_FORMAT_TEXT) { appendStringInfoSpaces(es->str, es->indent * 2); @@ -279,7 +240,7 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es, ExplainOpenGroup("Master Query", "Master Query", false, es); - ExplainMasterPlan(masterPlan, into, es, queryString, params, &planDuration); + ExplainMasterPlan(plan, into, es, queryString, params, planDuration); ExplainCloseGroup("Master Query", "Master Query", false, es); diff --git a/src/backend/distributed/planner/multi_planner.c b/src/backend/distributed/planner/multi_planner.c index d72f9db0c..c21665d9c 100644 --- a/src/backend/distributed/planner/multi_planner.c +++ b/src/backend/distributed/planner/multi_planner.c @@ -36,10 +36,15 @@ static List *relationRestrictionContextList = NIL; /* local function forward declarations */ static void CheckNodeIsDumpable(Node *node); - - -/* local function forward declarations */ static char * GetMultiPlanString(PlannedStmt *result); +static PlannedStmt * MultiQueryContainerNode(PlannedStmt *result, + struct MultiPlan *multiPlan); +static struct MultiPlan * CreatePhysicalPlan(Query *originalQuery, Query *query, + RelationRestrictionContext * + restrictionContext); +static RelationRestrictionContext * CreateAndPushRestrictionContext(void); +static RelationRestrictionContext * CurrentRestrictionContext(void); +static void PopRestrictionContext(void); /* Distributed planner hook */ @@ -123,7 +128,7 @@ multi_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) * target shards. SELECT queries go through the full logical plan/optimize/ * physical plan process needed to produce distributed query plans. */ -MultiPlan * +static MultiPlan * CreatePhysicalPlan(Query *originalQuery, Query *query, RelationRestrictionContext *restrictionContext) { diff --git a/src/backend/distributed/shared_library_init.c b/src/backend/distributed/shared_library_init.c index 509ab0381..102016c8a 100644 --- a/src/backend/distributed/shared_library_init.c +++ b/src/backend/distributed/shared_library_init.c @@ -295,30 +295,6 @@ RegisterCitusConfigVariables(void) 0, NULL, NULL, NULL); - DefineCustomBoolVariable( - "citus.explain_multi_logical_plan", - gettext_noop("Enables Explain to print out distributed logical plans."), - gettext_noop("We use this private configuration entry as a debugging aid. " - "If enabled, the Explain command prints out the optimized " - "logical plan for distributed queries."), - &ExplainMultiLogicalPlan, - false, - PGC_USERSET, - GUC_NO_SHOW_ALL, - NULL, NULL, NULL); - - DefineCustomBoolVariable( - "citus.explain_multi_physical_plan", - gettext_noop("Enables Explain to print out distributed physical plans."), - gettext_noop("We use this private configuration entry as a debugging aid. " - "If enabled, the Explain command prints out the physical " - "plan for distributed queries."), - &ExplainMultiPhysicalPlan, - false, - PGC_USERSET, - GUC_NO_SHOW_ALL, - NULL, NULL, NULL); - DefineCustomBoolVariable( "citus.explain_distributed_queries", gettext_noop("Enables Explain for distributed queries."), diff --git a/src/include/distributed/multi_explain.h b/src/include/distributed/multi_explain.h index 984b8e2ab..55f4bf75d 100644 --- a/src/include/distributed/multi_explain.h +++ b/src/include/distributed/multi_explain.h @@ -13,8 +13,6 @@ #include "executor/executor.h" /* Config variables managed via guc.c to explain distributed query plans */ -extern bool ExplainMultiLogicalPlan; -extern bool ExplainMultiPhysicalPlan; extern bool ExplainDistributedQueries; extern bool ExplainAllTasks; diff --git a/src/include/distributed/multi_planner.h b/src/include/distributed/multi_planner.h index 7c96b55bf..a425232fa 100644 --- a/src/include/distributed/multi_planner.h +++ b/src/include/distributed/multi_planner.h @@ -53,16 +53,8 @@ extern PlannedStmt * multi_planner(Query *parse, int cursorOptions, extern bool HasCitusToplevelNode(PlannedStmt *planStatement); struct MultiPlan; -extern struct MultiPlan * CreatePhysicalPlan(Query *originalQuery, Query *query, - RelationRestrictionContext * - restrictionContext); extern struct MultiPlan * GetMultiPlan(PlannedStmt *planStatement); -extern PlannedStmt * MultiQueryContainerNode(PlannedStmt *result, - struct MultiPlan *multiPlan); extern void multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index index, RangeTblEntry *rte); -extern RelationRestrictionContext * CreateAndPushRestrictionContext(void); -extern RelationRestrictionContext * CurrentRestrictionContext(void); -extern void PopRestrictionContext(void); #endif /* MULTI_PLANNER_H */