diff options
-rw-r--r-- | contrib/pg_stat_statements/pg_stat_statements.c | 14 | ||||
-rw-r--r-- | src/backend/commands/copyto.c | 2 | ||||
-rw-r--r-- | src/backend/commands/createas.c | 2 | ||||
-rw-r--r-- | src/backend/commands/explain.c | 2 | ||||
-rw-r--r-- | src/backend/commands/matview.c | 2 | ||||
-rw-r--r-- | src/backend/commands/portalcmds.c | 3 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 27 | ||||
-rw-r--r-- | src/backend/tcop/postgres.c | 7 | ||||
-rw-r--r-- | src/include/optimizer/optimizer.h | 5 | ||||
-rw-r--r-- | src/include/optimizer/planner.h | 8 | ||||
-rw-r--r-- | src/include/tcop/tcopprot.h | 4 | ||||
-rw-r--r-- | src/test/modules/delay_execution/delay_execution.c | 7 |
12 files changed, 58 insertions, 25 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index db1af36a705..f2187167c5c 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -338,7 +338,8 @@ static void pgss_post_parse_analyze(ParseState *pstate, Query *query, static PlannedStmt *pgss_planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); static void pgss_ExecutorStart(QueryDesc *queryDesc, int eflags); static void pgss_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, @@ -894,7 +895,8 @@ static PlannedStmt * pgss_planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams) + ParamListInfo boundParams, + ExplainState *es) { PlannedStmt *result; @@ -929,10 +931,10 @@ pgss_planner(Query *parse, { if (prev_planner_hook) result = prev_planner_hook(parse, query_string, cursorOptions, - boundParams); + boundParams, es); else result = standard_planner(parse, query_string, cursorOptions, - boundParams); + boundParams, es); } PG_FINALLY(); { @@ -978,10 +980,10 @@ pgss_planner(Query *parse, { if (prev_planner_hook) result = prev_planner_hook(parse, query_string, cursorOptions, - boundParams); + boundParams, es); else result = standard_planner(parse, query_string, cursorOptions, - boundParams); + boundParams, es); } PG_FINALLY(); { diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c index 67b94b91cae..e5781155cdf 100644 --- a/src/backend/commands/copyto.c +++ b/src/backend/commands/copyto.c @@ -796,7 +796,7 @@ BeginCopyTo(ParseState *pstate, /* plan the query */ plan = pg_plan_query(query, pstate->p_sourcetext, - CURSOR_OPT_PARALLEL_OK, NULL); + CURSOR_OPT_PARALLEL_OK, NULL, NULL); /* * With row-level security and a user using "COPY relation TO", we diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index dfd2ab8e862..1ccc2e55c64 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -321,7 +321,7 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, /* plan the query */ plan = pg_plan_query(query, pstate->p_sourcetext, - CURSOR_OPT_PARALLEL_OK, params); + CURSOR_OPT_PARALLEL_OK, params, NULL); /* * Use a snapshot with an updated command ID to ensure this query sees diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 06191cd8a85..e6edae0845c 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -351,7 +351,7 @@ standard_ExplainOneQuery(Query *query, int cursorOptions, INSTR_TIME_SET_CURRENT(planstart); /* plan the query */ - plan = pg_plan_query(query, queryString, cursorOptions, params); + plan = pg_plan_query(query, queryString, cursorOptions, params, es); INSTR_TIME_SET_CURRENT(planduration); INSTR_TIME_SUBTRACT(planduration, planstart); diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 188e26f0e6e..441de55ac24 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -426,7 +426,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query, CHECK_FOR_INTERRUPTS(); /* Plan the query which will generate data for the refresh. */ - plan = pg_plan_query(query, queryString, CURSOR_OPT_PARALLEL_OK, NULL); + plan = pg_plan_query(query, queryString, CURSOR_OPT_PARALLEL_OK, NULL, NULL); /* * Use a snapshot with an updated command ID to ensure this query sees diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index e7c8171c102..ec96c2efcd3 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -99,7 +99,8 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa elog(ERROR, "non-SELECT statement in DECLARE CURSOR"); /* Plan the query, applying the specified options */ - plan = pg_plan_query(query, pstate->p_sourcetext, cstmt->options, params); + plan = pg_plan_query(query, pstate->p_sourcetext, cstmt->options, params, + NULL); /* * Create a portal and copy the plan and query string into its memory. diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 6f06174cdab..c250433a2ef 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -279,6 +279,23 @@ static void create_partial_unique_paths(PlannerInfo *root, RelOptInfo *input_rel * * Query optimizer entry point * + * Inputs: + * parse: an analyzed-and-rewritten query tree for an optimizable statement + * query_string: source text for the query tree (used for error reports) + * cursorOptions: bitmask of CURSOR_OPT_XXX flags, see parsenodes.h + * boundParams: passed-in parameter values, or NULL if none + * es: ExplainState if being called from EXPLAIN, else NULL + * + * The result is a PlannedStmt tree. + * + * PARAM_EXTERN Param nodes within the parse tree can be replaced by Consts + * using values from boundParams, if those values are marked PARAM_FLAG_CONST. + * Parameter values not so marked are still relied on for estimation purposes. + * + * The ExplainState pointer is not currently used by the core planner, but it + * is passed through to some planner hooks so that they can report information + * back to EXPLAIN extension hooks. + * * To support loadable plugins that monitor or modify planner behavior, * we provide a hook variable that lets a plugin get control before and * after the standard planning process. The plugin would normally call @@ -290,14 +307,16 @@ static void create_partial_unique_paths(PlannerInfo *root, RelOptInfo *input_rel *****************************************************************************/ PlannedStmt * planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams) + ParamListInfo boundParams, ExplainState *es) { PlannedStmt *result; if (planner_hook) - result = (*planner_hook) (parse, query_string, cursorOptions, boundParams); + result = (*planner_hook) (parse, query_string, cursorOptions, + boundParams, es); else - result = standard_planner(parse, query_string, cursorOptions, boundParams); + result = standard_planner(parse, query_string, cursorOptions, + boundParams, es); pgstat_report_plan_id(result->planId, false); @@ -306,7 +325,7 @@ planner(Query *parse, const char *query_string, int cursorOptions, PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams) + ParamListInfo boundParams, ExplainState *es) { PlannedStmt *result; PlannerGlobal *glob; diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index d356830f756..7dd75a490aa 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -37,6 +37,7 @@ #include "catalog/pg_type.h" #include "commands/async.h" #include "commands/event_trigger.h" +#include "commands/explain_state.h" #include "commands/prepare.h" #include "common/pg_prng.h" #include "jit/jit.h" @@ -884,7 +885,7 @@ pg_rewrite_query(Query *query) */ PlannedStmt * pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, - ParamListInfo boundParams) + ParamListInfo boundParams, ExplainState *es) { PlannedStmt *plan; @@ -901,7 +902,7 @@ pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, ResetUsage(); /* call the optimizer */ - plan = planner(querytree, query_string, cursorOptions, boundParams); + plan = planner(querytree, query_string, cursorOptions, boundParams, es); if (log_planner_stats) ShowUsage("PLANNER STATISTICS"); @@ -997,7 +998,7 @@ pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, else { stmt = pg_plan_query(query, query_string, cursorOptions, - boundParams); + boundParams, NULL); } stmt_list = lappend(stmt_list, stmt); diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 04878f1f1c2..a34113903c0 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -24,6 +24,8 @@ #include "nodes/parsenodes.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ + /* * We don't want to include nodes/pathnodes.h here, because non-planner * code should generally treat PlannerInfo as an opaque typedef. @@ -104,7 +106,8 @@ extern PGDLLIMPORT bool enable_distinct_reordering; extern PlannedStmt *planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern Expr *expression_planner(Expr *expr); extern Expr *expression_planner_with_deps(Expr *expr, diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index 1bbef0018d5..c7ab466f5f1 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -22,11 +22,14 @@ #include "nodes/plannodes.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ + /* Hook for plugins to get control in planner() */ typedef PlannedStmt *(*planner_hook_type) (Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern PGDLLIMPORT planner_hook_type planner_hook; /* Hook for plugins to get control when grouping_planner() plans upper rels */ @@ -40,7 +43,8 @@ extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; extern PlannedStmt *standard_planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index a83cc4f4850..c1bcfdec673 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -20,6 +20,7 @@ #include "utils/guc.h" #include "utils/queryenvironment.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ extern PGDLLIMPORT CommandDest whereToSendOutput; extern PGDLLIMPORT const char *debug_query_string; @@ -63,7 +64,8 @@ extern List *pg_analyze_and_rewrite_withcb(RawStmt *parsetree, QueryEnvironment *queryEnv); extern PlannedStmt *pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern List *pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams); diff --git a/src/test/modules/delay_execution/delay_execution.c b/src/test/modules/delay_execution/delay_execution.c index 7bc97f84a1c..d933e9a6e53 100644 --- a/src/test/modules/delay_execution/delay_execution.c +++ b/src/test/modules/delay_execution/delay_execution.c @@ -40,17 +40,18 @@ static planner_hook_type prev_planner_hook = NULL; /* planner_hook function to provide the desired delay */ static PlannedStmt * delay_execution_planner(Query *parse, const char *query_string, - int cursorOptions, ParamListInfo boundParams) + int cursorOptions, ParamListInfo boundParams, + ExplainState *es) { PlannedStmt *result; /* Invoke the planner, possibly via a previous hook user */ if (prev_planner_hook) result = prev_planner_hook(parse, query_string, cursorOptions, - boundParams); + boundParams, es); else result = standard_planner(parse, query_string, cursorOptions, - boundParams); + boundParams, es); /* If enabled, delay by taking and releasing the specified lock */ if (post_planning_lock_id != 0) |