PG Bug reporting form <noreply@postgresql.org> writes:
> The following condensed recipe reproduces the error:
> create procedure callee(t regclass)
> language plpgsql as
> $body$
> begin
> raise notice 'callee: oid = %', t::oid;
> execute 'table ' || t;
> end;
> $body$;
> create procedure caller()
> language plpgsql as
> $body$
> begin
> create table table_name ();
> raise notice 'caller: oid = %', 'table_name'::regclass::oid;
> call callee('table_name');
> drop table table_name;
> end;
> $body$;
> call caller(); -- OK
> call caller(); -- ERROR: callee executed with OID of previous invocation!
Hmm. It's not just regclass: we're failing to track *any* dependencies
of the compiled CallStmt. So you can also break it by, say, dropping
and recreating the "callee" procedure.
The attached quick hack fixes the reported symptoms, but I wonder
if there is a better place to do it.
regards, tom lane
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 5700bfb5cd..9b54ed5c70 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -3564,9 +3564,22 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context)
if (query->commandType == CMD_UTILITY)
{
+ /* CALL requires bespoke 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);
+ (void) extract_query_dependencies_walker((Node *) callstmt->outargs,
+ context);
+ return false;
+ }
+
/*
- * Ignore utility statements, except those (such as EXPLAIN) that
- * contain a parsed-but-not-planned query.
+ * Ignore other utility statements, except those (such as EXPLAIN)
+ * that contain a parsed-but-not-planned query.
*/
query = UtilityContainsQuery(query->utilityStmt);
if (query == NULL)