Commit 6aba63ef authored by Fujii Masao's avatar Fujii Masao

Allow the planner-related functions and hook to accept the query string.

This commit adds query_string argument into the planner-related functions
and hook and allows us to pass the query string to them.

Currently there is no user of the query string passed. But the upcoming patch
for the planning counters will add the planning hook function into
pg_stat_statements and the function will need the query string. So this change
will be necessary for that patch.

Also this change is useful for some extensions that want to use the query
string in their planner hook function.

Author: Pascal Legrand, Julien Rouhaud
Reviewed-by: Yoshikazu Imai, Tom Lane, Fujii Masao
Discussion: https://postgr.es/m/CAOBaU_bU1m3_XF5qKYtSj1ua4dxd=FWDyh2SH4rSJAUUfsGmAQ@mail.gmail.com
Discussion: https://postgr.es/m/1583789487074-0.post@n3.nabble.com
parent 4a539a25
...@@ -1580,7 +1580,8 @@ BeginCopy(ParseState *pstate, ...@@ -1580,7 +1580,8 @@ BeginCopy(ParseState *pstate,
} }
/* plan the query */ /* 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 * With row level security and a user using "COPY relation TO", we
......
...@@ -329,7 +329,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, ...@@ -329,7 +329,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
Assert(query->commandType == CMD_SELECT); Assert(query->commandType == CMD_SELECT);
/* plan the query */ /* plan the query */
plan = pg_plan_query(query, CURSOR_OPT_PARALLEL_OK, params); plan = pg_plan_query(query, pstate->p_sourcetext,
CURSOR_OPT_PARALLEL_OK, params);
/* /*
* Use a snapshot with an updated command ID to ensure this query sees * Use a snapshot with an updated command ID to ensure this query sees
......
...@@ -376,7 +376,7 @@ ExplainOneQuery(Query *query, int cursorOptions, ...@@ -376,7 +376,7 @@ ExplainOneQuery(Query *query, int cursorOptions,
INSTR_TIME_SET_CURRENT(planstart); INSTR_TIME_SET_CURRENT(planstart);
/* plan the query */ /* 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_SET_CURRENT(planduration);
INSTR_TIME_SUBTRACT(planduration, planstart); INSTR_TIME_SUBTRACT(planduration, planstart);
......
...@@ -751,7 +751,7 @@ execute_sql_string(const char *sql) ...@@ -751,7 +751,7 @@ execute_sql_string(const char *sql)
NULL, NULL,
0, 0,
NULL); 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) foreach(lc2, stmt_list)
{ {
......
...@@ -391,7 +391,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query, ...@@ -391,7 +391,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
/* Plan the query which will generate data for the refresh. */ /* 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 * Use a snapshot with an updated command ID to ensure this query sees
......
...@@ -90,7 +90,7 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa ...@@ -90,7 +90,7 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa
elog(ERROR, "non-SELECT statement in DECLARE CURSOR"); elog(ERROR, "non-SELECT statement in DECLARE CURSOR");
/* Plan the query, applying the specified options */ /* Plan the query, applying the specified options */
plan = pg_plan_query(query, cstmt->options, params); plan = pg_plan_query(query, pstate->p_sourcetext, cstmt->options, params);
/* /*
* Create a portal and copy the plan and query string into its memory. * Create a portal and copy the plan and query string into its memory.
......
...@@ -510,6 +510,7 @@ init_execution_state(List *queryTree_list, ...@@ -510,6 +510,7 @@ init_execution_state(List *queryTree_list,
} }
else else
stmt = pg_plan_query(queryTree, stmt = pg_plan_query(queryTree,
fcache->src,
CURSOR_OPT_PARALLEL_OK, CURSOR_OPT_PARALLEL_OK,
NULL); NULL);
......
...@@ -264,19 +264,21 @@ static int common_prefix_cmp(const void *a, const void *b); ...@@ -264,19 +264,21 @@ static int common_prefix_cmp(const void *a, const void *b);
* *
*****************************************************************************/ *****************************************************************************/
PlannedStmt * PlannedStmt *
planner(Query *parse, int cursorOptions, ParamListInfo boundParams) planner(Query *parse, const char *query_string, int cursorOptions,
ParamListInfo boundParams)
{ {
PlannedStmt *result; PlannedStmt *result;
if (planner_hook) if (planner_hook)
result = (*planner_hook) (parse, cursorOptions, boundParams); result = (*planner_hook) (parse, query_string, cursorOptions, boundParams);
else else
result = standard_planner(parse, cursorOptions, boundParams); result = standard_planner(parse, query_string, cursorOptions, boundParams);
return result; return result;
} }
PlannedStmt * PlannedStmt *
standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) standard_planner(Query *parse, const char *query_string, int cursorOptions,
ParamListInfo boundParams)
{ {
PlannedStmt *result; PlannedStmt *result;
PlannerGlobal *glob; PlannerGlobal *glob;
......
...@@ -854,7 +854,8 @@ pg_rewrite_query(Query *query) ...@@ -854,7 +854,8 @@ pg_rewrite_query(Query *query)
* This is a thin wrapper around planner() and takes the same parameters. * This is a thin wrapper around planner() and takes the same parameters.
*/ */
PlannedStmt * PlannedStmt *
pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) pg_plan_query(Query *querytree, const char *query_string, int cursorOptions,
ParamListInfo boundParams)
{ {
PlannedStmt *plan; PlannedStmt *plan;
...@@ -871,7 +872,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) ...@@ -871,7 +872,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
ResetUsage(); ResetUsage();
/* call the optimizer */ /* call the optimizer */
plan = planner(querytree, cursorOptions, boundParams); plan = planner(querytree, query_string, cursorOptions, boundParams);
if (log_planner_stats) if (log_planner_stats)
ShowUsage("PLANNER STATISTICS"); ShowUsage("PLANNER STATISTICS");
...@@ -939,7 +940,8 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) ...@@ -939,7 +940,8 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
* The result is a list of PlannedStmt nodes. * The result is a list of PlannedStmt nodes.
*/ */
List * 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; List *stmt_list = NIL;
ListCell *query_list; ListCell *query_list;
...@@ -961,7 +963,8 @@ pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams) ...@@ -961,7 +963,8 @@ pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams)
} }
else else
{ {
stmt = pg_plan_query(query, cursorOptions, boundParams); stmt = pg_plan_query(query, query_string, cursorOptions,
boundParams);
} }
stmt_list = lappend(stmt_list, stmt); stmt_list = lappend(stmt_list, stmt);
...@@ -1152,7 +1155,7 @@ exec_simple_query(const char *query_string) ...@@ -1152,7 +1155,7 @@ exec_simple_query(const char *query_string)
querytree_list = pg_analyze_and_rewrite(parsetree, query_string, querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
NULL, 0, NULL); NULL, 0, NULL);
plantree_list = pg_plan_queries(querytree_list, plantree_list = pg_plan_queries(querytree_list, query_string,
CURSOR_OPT_PARALLEL_OK, NULL); CURSOR_OPT_PARALLEL_OK, NULL);
/* /*
......
...@@ -930,7 +930,8 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, ...@@ -930,7 +930,8 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist,
/* /*
* Generate the plan. * 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 */ /* Release snapshot if we got one */
if (snapshot_set) if (snapshot_set)
......
...@@ -102,7 +102,8 @@ typedef enum ...@@ -102,7 +102,8 @@ typedef enum
extern int force_parallel_mode; extern int force_parallel_mode;
extern bool parallel_leader_participation; extern bool parallel_leader_participation;
extern struct PlannedStmt *planner(Query *parse, int cursorOptions, extern struct PlannedStmt *planner(Query *parse, const char *query_string,
int cursorOptions,
struct ParamListInfoData *boundParams); struct ParamListInfoData *boundParams);
extern Expr *expression_planner(Expr *expr); extern Expr *expression_planner(Expr *expr);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
/* Hook for plugins to get control in planner() */ /* Hook for plugins to get control in planner() */
typedef PlannedStmt *(*planner_hook_type) (Query *parse, typedef PlannedStmt *(*planner_hook_type) (Query *parse,
const char *query_string,
int cursorOptions, int cursorOptions,
ParamListInfo boundParams); ParamListInfo boundParams);
extern PGDLLIMPORT planner_hook_type planner_hook; extern PGDLLIMPORT planner_hook_type planner_hook;
...@@ -37,7 +38,8 @@ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, ...@@ -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 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_string,
int cursorOptions,
ParamListInfo boundParams); ParamListInfo boundParams);
extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse,
......
...@@ -52,9 +52,11 @@ extern List *pg_analyze_and_rewrite_params(RawStmt *parsetree, ...@@ -52,9 +52,11 @@ extern List *pg_analyze_and_rewrite_params(RawStmt *parsetree,
ParserSetupHook parserSetup, ParserSetupHook parserSetup,
void *parserSetupArg, void *parserSetupArg,
QueryEnvironment *queryEnv); QueryEnvironment *queryEnv);
extern PlannedStmt *pg_plan_query(Query *querytree, int cursorOptions, extern PlannedStmt *pg_plan_query(Query *querytree, const char *query_string,
int cursorOptions,
ParamListInfo boundParams); ParamListInfo boundParams);
extern List *pg_plan_queries(List *querytrees, int cursorOptions, extern List *pg_plan_queries(List *querytrees, const char *query_string,
int cursorOptions,
ParamListInfo boundParams); ParamListInfo boundParams);
extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); extern bool check_max_stack_depth(int *newval, void **extra, GucSource source);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment