mirror of https://github.com/citusdata/citus.git
Merge pull request #1146 from citusdata/explain_duplication
Don't duplicate planner logic in multi_explain.cpull/1152/head
commit
a296aca257
|
@ -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,11 +118,7 @@ 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);
|
INSTR_TIME_SET_CURRENT(planStart);
|
||||||
|
|
||||||
/* plan the query */
|
/* plan the query */
|
||||||
|
@ -137,29 +127,33 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
|
||||||
INSTR_TIME_SET_CURRENT(planDuration);
|
INSTR_TIME_SET_CURRENT(planDuration);
|
||||||
INSTR_TIME_SUBTRACT(planDuration, planStart);
|
INSTR_TIME_SUBTRACT(planDuration, planStart);
|
||||||
|
|
||||||
|
/* if not a distributed query, use plain explain infrastructure */
|
||||||
|
if (!HasCitusToplevelNode(plan))
|
||||||
|
{
|
||||||
/* run it (if needed) and produce output */
|
/* run it (if needed) and produce output */
|
||||||
ExplainOnePlan(plan, into, es, queryString, params, &planDuration);
|
ExplainOnePlan(plan, into, es, queryString, params, &planDuration);
|
||||||
|
}
|
||||||
return;
|
else
|
||||||
|
{
|
||||||
|
MultiExplainOnePlan(plan, into, es, queryString, params, &planDuration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* standard_planner scribbles on it's input, but for deparsing we need the
|
* MultiExplainOnePlan explains the plan for an individual distributed query.
|
||||||
* unmodified form. So copy once we're sure it's a distributed query.
|
|
||||||
*/
|
*/
|
||||||
originalQuery = copyObject(query);
|
static void
|
||||||
|
MultiExplainOnePlan(PlannedStmt *plan, IntoClause *into,
|
||||||
/* measure the full planning time to display in EXPLAIN ANALYZE */
|
ExplainState *es, const char *queryString,
|
||||||
INSTR_TIME_SET_CURRENT(planStart);
|
ParamListInfo params, const instr_time *planDuration)
|
||||||
|
|
||||||
restrictionContext = CreateAndPushRestrictionContext();
|
|
||||||
|
|
||||||
PG_TRY();
|
|
||||||
{
|
{
|
||||||
/* call standard planner to modify the query structure before multi planning */
|
MultiPlan *multiPlan = NULL;
|
||||||
initialPlan = standard_planner(query, cursorOptions, params);
|
CmdType commandType = CMD_UNKNOWN;
|
||||||
|
Job *workerJob = NULL;
|
||||||
|
bool routerExecutablePlan = false;
|
||||||
|
|
||||||
commandType = initialPlan->commandType;
|
commandType = plan->commandType;
|
||||||
if (commandType == CMD_INSERT || commandType == CMD_UPDATE ||
|
if (commandType == CMD_INSERT || commandType == CMD_UPDATE ||
|
||||||
commandType == CMD_DELETE)
|
commandType == CMD_DELETE)
|
||||||
{
|
{
|
||||||
|
@ -171,38 +165,7 @@ MultiExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
multiPlan = CreatePhysicalPlan(originalQuery, query, restrictionContext);
|
multiPlan = GetMultiPlan(plan);
|
||||||
}
|
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
PopRestrictionContext();
|
|
||||||
PG_RE_THROW();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
PopRestrictionContext();
|
|
||||||
|
|
||||||
INSTR_TIME_SET_CURRENT(planDuration);
|
|
||||||
INSTR_TIME_SUBTRACT(planDuration, planStart);
|
|
||||||
|
|
||||||
if (ExplainMultiLogicalPlan)
|
|
||||||
{
|
|
||||||
MultiTreeRoot *multiTree = MultiLogicalPlanCreate(query);
|
|
||||||
char *logicalPlanString = CitusNodeToString(multiTree);
|
|
||||||
char *formattedPlanString = pretty_format_node_dump(logicalPlanString);
|
|
||||||
|
|
||||||
appendStringInfo(es->str, "logical plan:\n");
|
|
||||||
appendStringInfo(es->str, "%s\n", formattedPlanString);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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."),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue