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 */
|
||||
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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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."),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue