From 5ca152cecb4207178f1aa6d0f203bca0be5eb942 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 | 5 +++-- 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/tcop/utility.c | 3 ++- src/backend/utils/cache/plancache.c | 3 ++- src/include/commands/createas.h | 4 +++- src/include/optimizer/optimizer.h | 3 ++- src/include/optimizer/planner.h | 4 +++- src/include/tcop/tcopprot.h | 6 ++++-- 15 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index c93a788798..3719beeb98 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -1580,7 +1580,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 9f387b5f5f..3fe65a6c5d 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -225,7 +225,7 @@ create_ctas_nodata(List *tlist, IntoClause *into) ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, ParamListInfo params, QueryEnvironment *queryEnv, - char *completionTag) + const char *queryString, char *completionTag) { Query *query = castNode(Query, stmt->query); IntoClause *into = stmt->into; @@ -329,7 +329,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, 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 d189b8d573..7a04d0396c 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -363,7 +363,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 01de398dcb..f1590e1b89 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 1ee37c1aeb..dfb6cf72e2 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 7e5c805a1e..dd749ebc33 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -90,7 +90,7 @@ 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, cstmt->options, params); + plan = pg_plan_query(query, queryString, cstmt->options, params); /* * Create a portal and copy the plan and query string into its memory. diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index ac298c0295..8dd01995ad 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 d6f2153593..bb76dda576 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -264,19 +264,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 0a6f80963b..e7ac8036f1 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -854,7 +854,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; @@ -871,7 +872,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"); @@ -939,7 +940,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; @@ -961,7 +963,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); @@ -1152,7 +1155,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/tcop/utility.c b/src/backend/tcop/utility.c index b2c58bf862..5229411fd7 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1492,7 +1492,8 @@ ProcessUtilitySlow(ParseState *pstate, case T_CreateTableAsStmt: address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree, - params, queryEnv, completionTag); + params, queryEnv, queryString, + completionTag); break; case T_RefreshMatViewStmt: diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index c47be0ba4c..47122dfc7c 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/commands/createas.h b/src/include/commands/createas.h index 7743851a38..7a863dba0b 100644 --- a/src/include/commands/createas.h +++ b/src/include/commands/createas.h @@ -22,7 +22,9 @@ extern ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, - ParamListInfo params, QueryEnvironment *queryEnv, char *completionTag); + ParamListInfo params, QueryEnvironment + *queryEnv, const char *queryString, + char *completionTag); extern int GetIntoRelEFlags(IntoClause *intoClause); diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 5283995df8..302e47aa58 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 93df62d136..22bcf9c1e8 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 750ba4a3e2..69c7b16ac7 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