mirror of https://github.com/citusdata/citus.git
Don't duplicate planning logic in citus' explain hook.
Instead use pg_plan_query() like the normal explain does, and use that to explain the query. That's important because it allows to remove the duplicated planner logic from multi_explain - and that logic is about to get more complicated.pull/1146/head
parent
0f28a11970
commit
608bed0387
|
@ -77,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,
|
||||||
|
@ -98,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
|
||||||
|
|
||||||
|
@ -122,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 */
|
||||||
|
@ -135,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)
|
||||||
{
|
{
|
||||||
|
@ -169,24 +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 (!ExplainDistributedQueries)
|
if (!ExplainDistributedQueries)
|
||||||
{
|
{
|
||||||
|
@ -252,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);
|
||||||
|
@ -263,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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue