Make better use of ParseState in ProcessUtility

Pass ParseState into the functions called from
standard_ProcessUtility() instead passing the query string and query
environment separately.  No functionality change, but it makes the
notation consistent.  We had already started moving things into
that direction piece by piece, and this completes it.

Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/6e7aa4a1-be6a-1a75-b1f9-83a678e5184a@2ndquadrant.com
This commit is contained in:
Peter Eisentraut 2020-01-04 11:56:58 +01:00
parent d2e5e20e57
commit 3fd40b628c
9 changed files with 51 additions and 61 deletions

View File

@ -223,7 +223,7 @@ create_ctas_nodata(List *tlist, IntoClause *into)
* ExecCreateTableAs -- execute a CREATE TABLE AS command * ExecCreateTableAs -- execute a CREATE TABLE AS command
*/ */
ObjectAddress ObjectAddress
ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv, ParamListInfo params, QueryEnvironment *queryEnv,
char *completionTag) char *completionTag)
{ {
@ -270,7 +270,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
ExecuteStmt *estmt = castNode(ExecuteStmt, query->utilityStmt); ExecuteStmt *estmt = castNode(ExecuteStmt, query->utilityStmt);
Assert(!is_matview); /* excluded by syntax */ Assert(!is_matview); /* excluded by syntax */
ExecuteQuery(estmt, into, queryString, params, dest, completionTag); ExecuteQuery(pstate, estmt, into, params, dest, completionTag);
/* get object address that intorel_startup saved for us */ /* get object address that intorel_startup saved for us */
address = ((DR_intorel *) dest)->reladdr; address = ((DR_intorel *) dest)->reladdr;
@ -342,7 +342,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
UpdateActiveSnapshotCommandId(); UpdateActiveSnapshotCommandId();
/* Create a QueryDesc, redirecting output to our tuple receiver */ /* Create a QueryDesc, redirecting output to our tuple receiver */
queryDesc = CreateQueryDesc(plan, queryString, queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
GetActiveSnapshot(), InvalidSnapshot, GetActiveSnapshot(), InvalidSnapshot,
dest, params, queryEnv, 0); dest, params, queryEnv, 0);

View File

@ -139,9 +139,8 @@ static void escape_yaml(StringInfo buf, const char *str);
* execute an EXPLAIN command * execute an EXPLAIN command
*/ */
void void
ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv, ParamListInfo params, DestReceiver *dest)
DestReceiver *dest)
{ {
ExplainState *es = NewExplainState(); ExplainState *es = NewExplainState();
TupOutputState *tstate; TupOutputState *tstate;
@ -254,7 +253,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString,
{ {
ExplainOneQuery(lfirst_node(Query, l), ExplainOneQuery(lfirst_node(Query, l),
CURSOR_OPT_PARALLEL_OK, NULL, es, CURSOR_OPT_PARALLEL_OK, NULL, es,
queryString, params, queryEnv); pstate->p_sourcetext, params, pstate->p_queryEnv);
/* Separate plans with an appropriate separator */ /* Separate plans with an appropriate separator */
if (lnext(rewritten, l) != NULL) if (lnext(rewritten, l) != NULL)

View File

@ -39,14 +39,15 @@
* Execute SQL DECLARE CURSOR command. * Execute SQL DECLARE CURSOR command.
*/ */
void void
PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo params,
const char *queryString, bool isTopLevel) bool isTopLevel)
{ {
Query *query = castNode(Query, cstmt->query); Query *query = castNode(Query, cstmt->query);
List *rewritten; List *rewritten;
PlannedStmt *plan; PlannedStmt *plan;
Portal portal; Portal portal;
MemoryContext oldContext; MemoryContext oldContext;
char *queryString;
/* /*
* Disallow empty-string cursor name (conflicts with protocol-level * Disallow empty-string cursor name (conflicts with protocol-level
@ -92,7 +93,7 @@ PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params,
plan = pg_plan_query(query, cstmt->options, params); plan = pg_plan_query(query, cstmt->options, params);
/* /*
* Create a portal and copy the plan and queryString into its memory. * Create a portal and copy the plan and query string into its memory.
*/ */
portal = CreatePortal(cstmt->portalname, false, false); portal = CreatePortal(cstmt->portalname, false, false);
@ -100,7 +101,7 @@ PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params,
plan = copyObject(plan); plan = copyObject(plan);
queryString = pstrdup(queryString); queryString = pstrdup(pstate->p_sourcetext);
PortalDefineQuery(portal, PortalDefineQuery(portal,
NULL, NULL,

View File

@ -46,15 +46,16 @@
static HTAB *prepared_queries = NULL; static HTAB *prepared_queries = NULL;
static void InitQueryHashTable(void); static void InitQueryHashTable(void);
static ParamListInfo EvaluateParams(PreparedStatement *pstmt, List *params, static ParamListInfo EvaluateParams(ParseState *pstate,
const char *queryString, EState *estate); PreparedStatement *pstmt, List *params,
EState *estate);
static Datum build_regtype_array(Oid *param_types, int num_params); static Datum build_regtype_array(Oid *param_types, int num_params);
/* /*
* Implements the 'PREPARE' utility statement. * Implements the 'PREPARE' utility statement.
*/ */
void void
PrepareQuery(PrepareStmt *stmt, const char *queryString, PrepareQuery(ParseState *pstate, PrepareStmt *stmt,
int stmt_location, int stmt_len) int stmt_location, int stmt_len)
{ {
RawStmt *rawstmt; RawStmt *rawstmt;
@ -90,7 +91,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString,
* Create the CachedPlanSource before we do parse analysis, since it needs * Create the CachedPlanSource before we do parse analysis, since it needs
* to see the unmodified raw parse tree. * to see the unmodified raw parse tree.
*/ */
plansource = CreateCachedPlan(rawstmt, queryString, plansource = CreateCachedPlan(rawstmt, pstate->p_sourcetext,
CreateCommandTag(stmt->query)); CreateCommandTag(stmt->query));
/* Transform list of TypeNames to array of type OIDs */ /* Transform list of TypeNames to array of type OIDs */
@ -98,16 +99,8 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString,
if (nargs) if (nargs)
{ {
ParseState *pstate;
ListCell *l; ListCell *l;
/*
* typenameTypeId wants a ParseState to carry the source query string.
* Is it worth refactoring its API to avoid this?
*/
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
argtypes = (Oid *) palloc(nargs * sizeof(Oid)); argtypes = (Oid *) palloc(nargs * sizeof(Oid));
i = 0; i = 0;
@ -125,7 +118,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString,
* passed in from above us will not be visible to it), allowing * passed in from above us will not be visible to it), allowing
* information about unknown parameters to be deduced from context. * information about unknown parameters to be deduced from context.
*/ */
query = parse_analyze_varparams(rawstmt, queryString, query = parse_analyze_varparams(rawstmt, pstate->p_sourcetext,
&argtypes, &nargs); &argtypes, &nargs);
/* /*
@ -189,16 +182,11 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString,
* indicated by passing a non-null intoClause. The DestReceiver is already * indicated by passing a non-null intoClause. The DestReceiver is already
* set up correctly for CREATE TABLE AS, but we still have to make a few * set up correctly for CREATE TABLE AS, but we still have to make a few
* other adjustments here. * other adjustments here.
*
* Note: this is one of very few places in the code that needs to deal with
* two query strings at once. The passed-in queryString is that of the
* EXECUTE, which we might need for error reporting while processing the
* parameter expressions. The query_string that we copy from the plan
* source is that of the original PREPARE.
*/ */
void void
ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause, ExecuteQuery(ParseState *pstate,
const char *queryString, ParamListInfo params, ExecuteStmt *stmt, IntoClause *intoClause,
ParamListInfo params,
DestReceiver *dest, char *completionTag) DestReceiver *dest, char *completionTag)
{ {
PreparedStatement *entry; PreparedStatement *entry;
@ -229,8 +217,7 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
*/ */
estate = CreateExecutorState(); estate = CreateExecutorState();
estate->es_param_list_info = params; estate->es_param_list_info = params;
paramLI = EvaluateParams(entry, stmt->params, paramLI = EvaluateParams(pstate, entry, stmt->params, estate);
queryString, estate);
} }
/* Create a new portal to run the query in */ /* Create a new portal to run the query in */
@ -314,9 +301,9 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
/* /*
* EvaluateParams: evaluate a list of parameters. * EvaluateParams: evaluate a list of parameters.
* *
* pstate: parse state
* pstmt: statement we are getting parameters for. * pstmt: statement we are getting parameters for.
* params: list of given parameter expressions (raw parser output!) * params: list of given parameter expressions (raw parser output!)
* queryString: source text for error messages.
* estate: executor state to use. * estate: executor state to use.
* *
* Returns a filled-in ParamListInfo -- this can later be passed to * Returns a filled-in ParamListInfo -- this can later be passed to
@ -324,13 +311,12 @@ ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause,
* during query execution. * during query execution.
*/ */
static ParamListInfo static ParamListInfo
EvaluateParams(PreparedStatement *pstmt, List *params, EvaluateParams(ParseState *pstate, PreparedStatement *pstmt, List *params,
const char *queryString, EState *estate) EState *estate)
{ {
Oid *param_types = pstmt->plansource->param_types; Oid *param_types = pstmt->plansource->param_types;
int num_params = pstmt->plansource->num_params; int num_params = pstmt->plansource->num_params;
int nparams = list_length(params); int nparams = list_length(params);
ParseState *pstate;
ParamListInfo paramLI; ParamListInfo paramLI;
List *exprstates; List *exprstates;
ListCell *l; ListCell *l;
@ -354,9 +340,6 @@ EvaluateParams(PreparedStatement *pstmt, List *params,
*/ */
params = copyObject(params); params = copyObject(params);
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
i = 0; i = 0;
foreach(l, params) foreach(l, params)
{ {
@ -648,6 +631,11 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
/* Evaluate parameters, if any */ /* Evaluate parameters, if any */
if (entry->plansource->num_params) if (entry->plansource->num_params)
{ {
ParseState *pstate;
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
/* /*
* Need an EState to evaluate parameters; must not delete it till end * Need an EState to evaluate parameters; must not delete it till end
* of query, in case parameters are pass-by-reference. Note that the * of query, in case parameters are pass-by-reference. Note that the
@ -656,8 +644,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
*/ */
estate = CreateExecutorState(); estate = CreateExecutorState();
estate->es_param_list_info = params; estate->es_param_list_info = params;
paramLI = EvaluateParams(entry, execstmt->params,
queryString, estate); paramLI = EvaluateParams(pstate, entry, execstmt->params, estate);
} }
/* Replan if needed, and acquire a transient refcount */ /* Replan if needed, and acquire a transient refcount */

View File

@ -396,6 +396,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
pstate = make_parsestate(NULL); pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString; pstate->p_sourcetext = queryString;
pstate->p_queryEnv = queryEnv;
switch (nodeTag(parsetree)) switch (nodeTag(parsetree))
{ {
@ -500,8 +501,8 @@ standard_ProcessUtility(PlannedStmt *pstmt,
* Portal (cursor) manipulation * Portal (cursor) manipulation
*/ */
case T_DeclareCursorStmt: case T_DeclareCursorStmt:
PerformCursorOpen((DeclareCursorStmt *) parsetree, params, PerformCursorOpen(pstate, (DeclareCursorStmt *) parsetree, params,
queryString, isTopLevel); isTopLevel);
break; break;
case T_ClosePortalStmt: case T_ClosePortalStmt:
@ -558,13 +559,14 @@ standard_ProcessUtility(PlannedStmt *pstmt,
case T_PrepareStmt: case T_PrepareStmt:
CheckRestrictedOperation("PREPARE"); CheckRestrictedOperation("PREPARE");
PrepareQuery((PrepareStmt *) parsetree, queryString, PrepareQuery(pstate, (PrepareStmt *) parsetree,
pstmt->stmt_location, pstmt->stmt_len); pstmt->stmt_location, pstmt->stmt_len);
break; break;
case T_ExecuteStmt: case T_ExecuteStmt:
ExecuteQuery((ExecuteStmt *) parsetree, NULL, ExecuteQuery(pstate,
queryString, params, (ExecuteStmt *) parsetree, NULL,
params,
dest, completionTag); dest, completionTag);
break; break;
@ -667,8 +669,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
break; break;
case T_ExplainStmt: case T_ExplainStmt:
ExplainQuery(pstate, (ExplainStmt *) parsetree, queryString, params, ExplainQuery(pstate, (ExplainStmt *) parsetree, params, dest);
queryEnv, dest);
break; break;
case T_AlterSystemStmt: case T_AlterSystemStmt:
@ -1490,9 +1491,8 @@ ProcessUtilitySlow(ParseState *pstate,
break; break;
case T_CreateTableAsStmt: case T_CreateTableAsStmt:
address = ExecCreateTableAs((CreateTableAsStmt *) parsetree, address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree,
queryString, params, queryEnv, params, queryEnv, completionTag);
completionTag);
break; break;
case T_RefreshMatViewStmt: case T_RefreshMatViewStmt:

View File

@ -21,7 +21,7 @@
#include "utils/queryenvironment.h" #include "utils/queryenvironment.h"
extern ObjectAddress ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, extern ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv, char *completionTag); ParamListInfo params, QueryEnvironment *queryEnv, char *completionTag);
extern int GetIntoRelEFlags(IntoClause *intoClause); extern int GetIntoRelEFlags(IntoClause *intoClause);

View File

@ -64,8 +64,8 @@ typedef const char *(*explain_get_index_name_hook_type) (Oid indexId);
extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook; extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook;
extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest); ParamListInfo params, DestReceiver *dest);
extern ExplainState *NewExplainState(void); extern ExplainState *NewExplainState(void);

View File

@ -15,11 +15,12 @@
#define PORTALCMDS_H #define PORTALCMDS_H
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "parser/parse_node.h"
#include "utils/portal.h" #include "utils/portal.h"
extern void PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, extern void PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo params,
const char *queryString, bool isTopLevel); bool isTopLevel);
extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest,
char *completionTag); char *completionTag);

View File

@ -35,10 +35,11 @@ typedef struct
/* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */ /* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */
extern void PrepareQuery(PrepareStmt *stmt, const char *queryString, extern void PrepareQuery(ParseState *pstate, PrepareStmt *stmt,
int stmt_location, int stmt_len); int stmt_location, int stmt_len);
extern void ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause, extern void ExecuteQuery(ParseState *pstate,
const char *queryString, ParamListInfo params, ExecuteStmt *stmt, IntoClause *intoClause,
ParamListInfo params,
DestReceiver *dest, char *completionTag); DestReceiver *dest, char *completionTag);
extern void DeallocateQuery(DeallocateStmt *stmt); extern void DeallocateQuery(DeallocateStmt *stmt);
extern void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, extern void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into,