diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 09e331629e5..c044c1dbce2 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -2031,7 +2031,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 655bb55c287..edcf62d57a8 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 6d4d8ac0339..9672c655ff6 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -1549,7 +1549,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 b83a7eaac90..4640225dd48 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -2429,9 +2429,6 @@ GetCommandLogLevel(Node *parsetree) { LogStmtLevel lev; - if (parsetree == NULL) - return LOGSTMT_ALL; - switch (nodeTag(parsetree)) { /* raw plannable queries */ @@ -2535,7 +2532,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 0e210a0d1c5..59099960a8b 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -139,7 +139,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 */ @@ -221,7 +221,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 */ @@ -659,7 +659,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, @@ -887,6 +889,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 ea4ecac08a9..e6dba978a9a 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 */