Merge pull request #1146 from citusdata/explain_duplication

Don't duplicate planner logic in multi_explain.c
pull/1152/head
Andres Freund 2017-01-20 13:58:48 -08:00 committed by GitHub
commit a296aca257
5 changed files with 52 additions and 120 deletions

View File

@ -52,8 +52,6 @@
/* Config variables that enable printing distributed query plans */ /* Config variables that enable printing distributed query plans */
bool ExplainMultiLogicalPlan = false;
bool ExplainMultiPhysicalPlan = false;
bool ExplainDistributedQueries = true; bool ExplainDistributedQueries = true;
bool ExplainAllTasks = false; bool ExplainAllTasks = false;
@ -79,6 +77,9 @@ static void ExplainTask(Task *task, int placementIndex, List *explainOutputList,
static void ExplainTaskPlacement(ShardPlacement *taskPlacement, List *explainOutputList, static void ExplainTaskPlacement(ShardPlacement *taskPlacement, List *explainOutputList,
ExplainState *es); ExplainState *es);
static StringInfo BuildRemoteExplainQuery(char *queryString, 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 Explain functions copied from explain.c */
static void ExplainOpenGroup(const char *objtype, const char *labelname, static void ExplainOpenGroup(const char *objtype, const char *labelname,
@ -100,17 +101,10 @@ void
MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es, MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
const char *queryString, ParamListInfo params) 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 planStart;
instr_time planDuration; instr_time planDuration;
Query *originalQuery = NULL;
RelationRestrictionContext *restrictionContext = NULL;
bool localQuery = !NeedsDistributedPlanning(query);
int cursorOptions = 0; int cursorOptions = 0;
PlannedStmt *plan = NULL;
#if PG_VERSION_NUM >= 90600 #if PG_VERSION_NUM >= 90600
@ -124,85 +118,54 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
} }
#endif #endif
/* handle local queries in the same way as ExplainOneQuery */ /* plan query, just like ExplainOneQuery does */
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 */
INSTR_TIME_SET_CURRENT(planStart); INSTR_TIME_SET_CURRENT(planStart);
restrictionContext = CreateAndPushRestrictionContext(); /* plan the query */
plan = pg_plan_query(query, cursorOptions, params);
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();
INSTR_TIME_SET_CURRENT(planDuration); INSTR_TIME_SET_CURRENT(planDuration);
INSTR_TIME_SUBTRACT(planDuration, planStart); INSTR_TIME_SUBTRACT(planDuration, planStart);
if (ExplainMultiLogicalPlan) /* if not a distributed query, use plain explain infrastructure */
if (!HasCitusToplevelNode(plan))
{ {
MultiTreeRoot *multiTree = MultiLogicalPlanCreate(query); /* run it (if needed) and produce output */
char *logicalPlanString = CitusNodeToString(multiTree); ExplainOnePlan(plan, into, es, queryString, params, &planDuration);
char *formattedPlanString = pretty_format_node_dump(logicalPlanString); }
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) multiPlan = GetMultiPlan(plan);
{
char *physicalPlanString = CitusNodeToString(multiPlan);
char *formattedPlanString = pretty_format_node_dump(physicalPlanString);
appendStringInfo(es->str, "physical plan:\n");
appendStringInfo(es->str, "%s\n", formattedPlanString);
}
if (!ExplainDistributedQueries) if (!ExplainDistributedQueries)
{ {
@ -268,8 +231,6 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
if (!routerExecutablePlan) if (!routerExecutablePlan)
{ {
PlannedStmt *masterPlan = MultiQueryContainerNode(initialPlan, multiPlan);
if (es->format == EXPLAIN_FORMAT_TEXT) if (es->format == EXPLAIN_FORMAT_TEXT)
{ {
appendStringInfoSpaces(es->str, es->indent * 2); appendStringInfoSpaces(es->str, es->indent * 2);
@ -279,7 +240,7 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
ExplainOpenGroup("Master Query", "Master Query", false, 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); ExplainCloseGroup("Master Query", "Master Query", false, es);

View File

@ -36,10 +36,15 @@ static List *relationRestrictionContextList = NIL;
/* local function forward declarations */ /* local function forward declarations */
static void CheckNodeIsDumpable(Node *node); static void CheckNodeIsDumpable(Node *node);
/* local function forward declarations */
static char * GetMultiPlanString(PlannedStmt *result); 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 */ /* 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/ * target shards. SELECT queries go through the full logical plan/optimize/
* physical plan process needed to produce distributed query plans. * physical plan process needed to produce distributed query plans.
*/ */
MultiPlan * static MultiPlan *
CreatePhysicalPlan(Query *originalQuery, Query *query, CreatePhysicalPlan(Query *originalQuery, Query *query,
RelationRestrictionContext *restrictionContext) RelationRestrictionContext *restrictionContext)
{ {

View File

@ -295,30 +295,6 @@ RegisterCitusConfigVariables(void)
0, 0,
NULL, NULL, NULL); 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( DefineCustomBoolVariable(
"citus.explain_distributed_queries", "citus.explain_distributed_queries",
gettext_noop("Enables Explain for distributed queries."), gettext_noop("Enables Explain for distributed queries."),

View File

@ -13,8 +13,6 @@
#include "executor/executor.h" #include "executor/executor.h"
/* Config variables managed via guc.c to explain distributed query plans */ /* Config variables managed via guc.c to explain distributed query plans */
extern bool ExplainMultiLogicalPlan;
extern bool ExplainMultiPhysicalPlan;
extern bool ExplainDistributedQueries; extern bool ExplainDistributedQueries;
extern bool ExplainAllTasks; extern bool ExplainAllTasks;

View File

@ -53,16 +53,8 @@ extern PlannedStmt * multi_planner(Query *parse, int cursorOptions,
extern bool HasCitusToplevelNode(PlannedStmt *planStatement); extern bool HasCitusToplevelNode(PlannedStmt *planStatement);
struct MultiPlan; struct MultiPlan;
extern struct MultiPlan * CreatePhysicalPlan(Query *originalQuery, Query *query,
RelationRestrictionContext *
restrictionContext);
extern struct MultiPlan * GetMultiPlan(PlannedStmt *planStatement); extern struct MultiPlan * GetMultiPlan(PlannedStmt *planStatement);
extern PlannedStmt * MultiQueryContainerNode(PlannedStmt *result,
struct MultiPlan *multiPlan);
extern void multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, extern void multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo,
Index index, RangeTblEntry *rte); Index index, RangeTblEntry *rte);
extern RelationRestrictionContext * CreateAndPushRestrictionContext(void);
extern RelationRestrictionContext * CurrentRestrictionContext(void);
extern void PopRestrictionContext(void);
#endif /* MULTI_PLANNER_H */ #endif /* MULTI_PLANNER_H */