Skip to content

Commit 883c27a

Browse files
committed
Fix possible loss of sync between rectypeid and underlying PLpgSQL_type.
When revalidate_rectypeid() acts to update a stale record type OID in plpgsql's data structures, it fixes the active PLpgSQL_rec struct as well as the PLpgSQL_type struct it references. However, the latter is shared across function executions while the former is not. In a later function execution, the PLpgSQL_rec struct would be reinitialized by copy_plpgsql_datums and would then contain a stale type OID, typically leading to "could not open relation with OID NNNN" errors. revalidate_rectypeid() can easily fix this, fortunately, just by treating typ->typoid as authoritative. Per report and diagnosis from Ashutosh Sharma, though this is not his suggested fix. Back-patch to v11 where this code came in. Discussion: https://postgr.es/m/CAE9k0Pkd4dZwt9J5pS9xhJFWpUtqs05C9xk_GEwPzYdV=GxwWg@mail.gmail.com
1 parent 50fa688 commit 883c27a

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/pl/plpgsql/src/expected/plpgsql_record.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,12 @@ select sillyaddtwo(42);
476476
44
477477
(1 row)
478478

479+
select sillyaddtwo(43);
480+
sillyaddtwo
481+
-------------
482+
45
483+
(1 row)
484+
479485
-- check access to system columns in a record variable
480486
create function sillytrig() returns trigger language plpgsql as
481487
$$begin

src/pl/plpgsql/src/pl_exec.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6853,7 +6853,16 @@ revalidate_rectypeid(PLpgSQL_rec *rec)
68536853
Assert(typ != NULL);
68546854
if (typ->tcache &&
68556855
typ->tcache->tupDesc_identifier == typ->tupdesc_id)
6856-
return; /* known up-to-date */
6856+
{
6857+
/*
6858+
* Although *typ is known up-to-date, it's possible that rectypeid
6859+
* isn't, because *rec is cloned during each function startup from a
6860+
* copy that we don't have a good way to update. Hence, forcibly fix
6861+
* rectypeid before returning.
6862+
*/
6863+
rec->rectypeid = typ->typoid;
6864+
return;
6865+
}
68576866

68586867
/*
68596868
* typcache entry has suffered invalidation, so re-look-up the type name

src/pl/plpgsql/src/sql/plpgsql_record.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ drop table mutable2;
303303
select sillyaddtwo(42); -- fail
304304
create table mutable2(f0 text, f1 int, f2 text);
305305
select sillyaddtwo(42);
306+
select sillyaddtwo(43);
306307

307308
-- check access to system columns in a record variable
308309

0 commit comments

Comments
 (0)