mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Collect dependency information for parsed CallStmts.
Parse analysis of a CallStmt will inject mutable information,
for instance the OID of the called procedure, so that subsequent
DDL may create a need to re-parse the CALL. We failed to detect
this for CALLs in plpgsql routines, because no dependency information
was collected when putting a CallStmt into the plan cache. That
could lead to misbehavior or strange errors such as "cache lookup
failed".
Before commit ee895a655
, the issue would only manifest for CALLs
appearing in atomic contexts, because we re-planned non-atomic
CALLs every time through anyway.
It is now apparent that extract_query_dependencies() probably
needs a special case for every utility statement type for which
stmt_requires_parse_analysis() returns true. I wanted to add
something like Assert(!stmt_requires_parse_analysis(...)) when
falling out of extract_query_dependencies_walker without doing
anything, but there are API issues as well as a more fundamental
point: stmt_requires_parse_analysis is supposed to be applied to
raw parser output, so it'd be cheating to assume it will give the
correct answer for post-parse-analysis trees. I contented myself
with adding a comment.
Per bug #18131 from Christian Stork. Back-patch to all supported
branches.
Discussion: https://postgr.es/m/18131-576854e79c5cd264@postgresql.org
This commit is contained in:
@ -2889,8 +2889,25 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
|
||||
if (query->commandType == CMD_UTILITY)
|
||||
{
|
||||
/*
|
||||
* Ignore utility statements, except those (such as EXPLAIN) that
|
||||
* contain a parsed-but-not-planned query.
|
||||
* This logic must handle any utility command for which parse
|
||||
* analysis was nontrivial (cf. stmt_requires_parse_analysis).
|
||||
*
|
||||
* Notably, CALL requires its own processing.
|
||||
*/
|
||||
if (IsA(query->utilityStmt, CallStmt))
|
||||
{
|
||||
CallStmt *callstmt = (CallStmt *) query->utilityStmt;
|
||||
|
||||
/* We need not examine funccall, just the transformed exprs */
|
||||
(void) extract_query_dependencies_walker((Node *) callstmt->funcexpr,
|
||||
context);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore other utility statements, except those (such as EXPLAIN)
|
||||
* that contain a parsed-but-not-planned query. For those, we
|
||||
* just need to transfer our attention to the contained query.
|
||||
*/
|
||||
query = UtilityContainsQuery(query->utilityStmt);
|
||||
if (query == NULL)
|
||||
|
Reference in New Issue
Block a user