diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 7ba1fd9066..cfa4a24686 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -2037,7 +2037,9 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, * Parameter datatypes are driven by parserSetup hook if provided, * otherwise we use the fixed parameter list. */ - if (plan->parserSetup != NULL) + if (parsetree == NULL) + stmt_list = NIL; + else if (plan->parserSetup != NULL) { Assert(plan->nargs == 0); stmt_list = pg_analyze_and_rewrite_params(parsetree, diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index bd78e94985..cc569eddd5 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -288,17 +288,13 @@ transformStmt(ParseState *pstate, Node *parseTree) * Returns true if a snapshot must be set before doing parse analysis * on the given raw parse tree. * - * Classification here should match transformStmt(); but we also have to - * allow a NULL input (for Parse/Bind of an empty query string). + * Classification here should match transformStmt(). */ bool analyze_requires_snapshot(Node *parseTree) { bool result; - if (parseTree == NULL) - return false; - switch (nodeTag(parseTree)) { /* diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 61f17bf1e9..cc62b2cfe8 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1546,7 +1546,9 @@ exec_bind_message(StringInfo input_message) * snapshot active till we're done, so that plancache.c doesn't have to * take new ones. */ - if (numParams > 0 || analyze_requires_snapshot(psrc->raw_parse_tree)) + if (numParams > 0 || + (psrc->raw_parse_tree && + analyze_requires_snapshot(psrc->raw_parse_tree))) { PushActiveSnapshot(GetTransactionSnapshot()); snapshot_set = true; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 422911cde0..58f78ce50d 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -2485,9 +2485,6 @@ GetCommandLogLevel(Node *parsetree) { LogStmtLevel lev; - if (parsetree == NULL) - return LOGSTMT_ALL; - switch (nodeTag(parsetree)) { /* raw plannable queries */ @@ -2592,7 +2589,7 @@ GetCommandLogLevel(Node *parsetree) /* Look through an EXECUTE to the referenced stmt */ ps = FetchPreparedStatement(stmt->name, false); - if (ps) + if (ps && ps->plansource->raw_parse_tree) lev = GetCommandLogLevel(ps->plansource->raw_parse_tree); else lev = LOGSTMT_ALL; diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index 26ef2fa6ff..d85ea1bbd3 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -141,7 +141,7 @@ InitPlanCache(void) * Once constructed, the cached plan can be made longer-lived, if needed, * by calling SaveCachedPlan. * - * raw_parse_tree: output of raw_parser() + * raw_parse_tree: output of raw_parser(), or NULL if empty query * query_string: original query text * commandTag: compile-time-constant tag for query, or NULL if empty query */ @@ -232,7 +232,7 @@ CreateCachedPlan(Node *raw_parse_tree, * invalidation, so plan use must be completed in the current transaction, * and DDL that might invalidate the querytree_list must be avoided as well. * - * raw_parse_tree: output of raw_parser() + * raw_parse_tree: output of raw_parser(), or NULL if empty query * query_string: original query text * commandTag: compile-time-constant tag for query, or NULL if empty query */ @@ -699,7 +699,9 @@ RevalidateCachedQuery(CachedPlanSource *plansource) * the cache. */ rawtree = copyObject(plansource->raw_parse_tree); - if (plansource->parserSetup != NULL) + if (rawtree == NULL) + tlist = NIL; + else if (plansource->parserSetup != NULL) tlist = pg_analyze_and_rewrite_params(rawtree, plansource->query_string, plansource->parserSetup, @@ -928,6 +930,7 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, */ snapshot_set = false; if (!ActiveSnapshotSet() && + plansource->raw_parse_tree && analyze_requires_snapshot(plansource->raw_parse_tree)) { PushActiveSnapshot(GetTransactionSnapshot()); diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index 56bf4bb7af..2622ceb54b 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -76,7 +76,7 @@ typedef struct CachedPlanSource { int magic; /* should equal CACHEDPLANSOURCE_MAGIC */ - Node *raw_parse_tree; /* output of raw_parser() */ + Node *raw_parse_tree; /* output of raw_parser(), or NULL */ const char *query_string; /* source text of query */ const char *commandTag; /* command tag (a constant!), or NULL */ Oid *param_types; /* array of parameter type OIDs, or NULL */