From 08d422275ba6d2c476546bf438c6c687f10fff07 Mon Sep 17 00:00:00 2001 From: Julien Rouhaud Date: Thu, 28 Mar 2019 13:33:23 +0100 Subject: [PATCH 1/2] Pass query string to the planner --- src/backend/commands/copy.c | 3 ++- src/backend/commands/createas.c | 3 ++- src/backend/commands/explain.c | 2 +- src/backend/commands/extension.c | 2 +- src/backend/commands/matview.c | 2 +- src/backend/commands/portalcmds.c | 2 +- src/backend/executor/functions.c | 1 + src/backend/optimizer/plan/planner.c | 10 ++++++---- src/backend/tcop/postgres.c | 13 ++++++++----- src/backend/utils/cache/plancache.c | 3 ++- src/include/optimizer/optimizer.h | 3 ++- src/include/optimizer/planner.h | 4 +++- src/include/tcop/tcopprot.h | 6 ++++-- 13 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index e17d8c760f..ad3940e68a 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1579,7 +1579,8 @@ BeginCopy(ParseState *pstate, } /* plan the query */ - plan = pg_plan_query(query, CURSOR_OPT_PARALLEL_OK, NULL); + plan = pg_plan_query(query, pstate->p_sourcetext, + CURSOR_OPT_PARALLEL_OK, 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 b7d220699f..a8ddc0857b 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -330,7 +330,8 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, Assert(query->commandType == CMD_SELECT); /* plan the query */ - plan = pg_plan_query(query, CURSOR_OPT_PARALLEL_OK, params); + plan = pg_plan_query(query, queryString, CURSOR_OPT_PARALLEL_OK, + params); /* * 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 62fb3434a3..7fc03b7acd 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -364,7 +364,7 @@ ExplainOneQuery(Query *query, int cursorOptions, INSTR_TIME_SET_CURRENT(planstart); /* plan the query */ - plan = pg_plan_query(query, cursorOptions, params); + plan = pg_plan_query(query, queryString, cursorOptions, params); INSTR_TIME_SET_CURRENT(planduration); INSTR_TIME_SUBTRACT(planduration, planstart); diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index a04b0c9e57..2a24fd3a8f 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -740,7 +740,7 @@ execute_sql_string(const char *sql) NULL, 0, NULL); - stmt_list = pg_plan_queries(stmt_list, CURSOR_OPT_PARALLEL_OK, NULL); + stmt_list = pg_plan_queries(stmt_list, sql, CURSOR_OPT_PARALLEL_OK, NULL); foreach(lc2, stmt_list) { diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 537d0e8cef..6c88a16eb1 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -391,7 +391,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, 0, NULL); + plan = pg_plan_query(query, queryString, 0, 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 83f9959d54..e390776716 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -89,7 +89,7 @@ PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, elog(ERROR, "non-SELECT statement in DECLARE CURSOR"); /* Plan the query, applying the specified options */ - plan = pg_plan_query(query, cstmt->options, params); + plan = pg_plan_query(query, queryString, cstmt->options, params); /* * Create a portal and copy the plan and queryString into its memory. diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 83337c2eed..0eb597ecd0 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -505,6 +505,7 @@ init_execution_state(List *queryTree_list, } else stmt = pg_plan_query(queryTree, + fcache->src, CURSOR_OPT_PARALLEL_OK, NULL); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 17c5f086fb..eca6662201 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -265,19 +265,21 @@ static int common_prefix_cmp(const void *a, const void *b); * *****************************************************************************/ PlannedStmt * -planner(Query *parse, int cursorOptions, ParamListInfo boundParams) +planner(Query *parse, const char *query_text, int cursorOptions, + ParamListInfo boundParams) { PlannedStmt *result; if (planner_hook) - result = (*planner_hook) (parse, cursorOptions, boundParams); + result = (*planner_hook) (parse, query_text, cursorOptions, boundParams); else - result = standard_planner(parse, cursorOptions, boundParams); + result = standard_planner(parse, query_text, cursorOptions, boundParams); return result; } PlannedStmt * -standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) +standard_planner(Query *parse, const char *querytext, int cursorOptions, + ParamListInfo boundParams) { PlannedStmt *result; PlannerGlobal *glob; diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 82894eadc6..c491e07c27 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -853,7 +853,8 @@ pg_rewrite_query(Query *query) * This is a thin wrapper around planner() and takes the same parameters. */ PlannedStmt * -pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) +pg_plan_query(Query *querytree, const char *query_text, int cursorOptions, + ParamListInfo boundParams) { PlannedStmt *plan; @@ -870,7 +871,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) ResetUsage(); /* call the optimizer */ - plan = planner(querytree, cursorOptions, boundParams); + plan = planner(querytree, query_text, cursorOptions, boundParams); if (log_planner_stats) ShowUsage("PLANNER STATISTICS"); @@ -938,7 +939,8 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) * The result is a list of PlannedStmt nodes. */ List * -pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams) +pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, + ParamListInfo boundParams) { List *stmt_list = NIL; ListCell *query_list; @@ -960,7 +962,8 @@ pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams) } else { - stmt = pg_plan_query(query, cursorOptions, boundParams); + stmt = pg_plan_query(query, query_string, cursorOptions, + boundParams); } stmt_list = lappend(stmt_list, stmt); @@ -1151,7 +1154,7 @@ exec_simple_query(const char *query_string) querytree_list = pg_analyze_and_rewrite(parsetree, query_string, NULL, 0, NULL); - plantree_list = pg_plan_queries(querytree_list, + plantree_list = pg_plan_queries(querytree_list, query_string, CURSOR_OPT_PARALLEL_OK, NULL); /* Done with the snapshot used for parsing/planning */ diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index abc3062892..b4ae9fde84 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -930,7 +930,8 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, /* * Generate the plan. */ - plist = pg_plan_queries(qlist, plansource->cursor_options, boundParams); + plist = pg_plan_queries(qlist, plansource->query_string, + plansource->cursor_options, boundParams); /* Release snapshot if we got one */ if (snapshot_set) diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 6b8fd3f285..d99ee69efd 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -102,7 +102,8 @@ typedef enum extern int force_parallel_mode; extern bool parallel_leader_participation; -extern struct PlannedStmt *planner(Query *parse, int cursorOptions, +extern struct PlannedStmt *planner(Query *parse, const char *query_text, + int cursorOptions, struct ParamListInfoData *boundParams); extern Expr *expression_planner(Expr *expr); diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index 8d30b94215..c4e83e3a73 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -24,6 +24,7 @@ /* Hook for plugins to get control in planner() */ typedef PlannedStmt *(*planner_hook_type) (Query *parse, + const char *query_text, int cursorOptions, ParamListInfo boundParams); extern PGDLLIMPORT planner_hook_type planner_hook; @@ -37,7 +38,8 @@ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; -extern PlannedStmt *standard_planner(Query *parse, int cursorOptions, +extern PlannedStmt *standard_planner(Query *parse, const char *query_text, + int cursorOptions, ParamListInfo boundParams); extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index ec21f7e45c..716b040c04 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -52,9 +52,11 @@ extern List *pg_analyze_and_rewrite_params(RawStmt *parsetree, ParserSetupHook parserSetup, void *parserSetupArg, QueryEnvironment *queryEnv); -extern PlannedStmt *pg_plan_query(Query *querytree, int cursorOptions, +extern PlannedStmt *pg_plan_query(Query *querytree, const char *query_text, + int cursorOptions, ParamListInfo boundParams); -extern List *pg_plan_queries(List *querytrees, int cursorOptions, +extern List *pg_plan_queries(List *querytrees, const char *query_text, + int cursorOptions, ParamListInfo boundParams); extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); -- 2.20.1