Re: Calling PLpgSQL function with composite type fails with an error: "ERROR: could not open relation with OID ..."

From: Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: Calling PLpgSQL function with composite type fails with an error: "ERROR: could not open relation with OID ..."
Date: 2019-12-26 11:32:05
Message-ID: CAE9k0PnjG_O+Lh=Aq41S=MD820oVKAmb3koLruMzqBwgmCrF8w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

The issue here is that PLpgSQL_rec structure being updated by
revalidate_rectypeid() is actually a local/duplicate copy of the
PLpgSQL_rec structure available in plpgsql_HashTable (refer to
copy_plpgsql_datums() where you would notice that if datum type is
PLPGSQL_DTYPE_REC we actually mempcy() the PLpgSQL_rec structure
available in func >datums[] array). This basically means that the
rectypeid field updated post typcache entry validation in
revalidation_rectypeid() is actually a field in duplicate copy of
PLpgSQL_rec structure, not the original copy of it available in
func->datums[]. Hence, when the same function is executed for the
second time, the rectypeid field of PLpgSQL_rec structure being
reloaded from the func->datums[] actually contains the stale value
however the typcache entry in it is up-to-date which means
revalidation_rectypeid() returns immediately leaving a stale value in
rectypeid. This causes the function make_expanded_record_from_typeid()
to use the outdated value in rec->rectypeid resulting into the given
error.

To fix this, I think instead of using rec->rectypeid field we should
try using rec->datatype->typoid when calling
make_expanded_record_from_typeid(). Here is the change that I'm
suggesting:

--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -6942,7 +6942,7 @@ make_expanded_record_for_rec(PLpgSQL_execstate *estate,
newerh = make_expanded_record_from_exprecord(srcerh,
mcontext);
else
- newerh = make_expanded_record_from_typeid(rec->rectypeid, -1,
+ newerh = make_expanded_record_from_typeid(rec->datatype->typoid, -1,

Thoughts ?

--
With Regards,
Ashutosh Sharma
EnterpriseDB:http://www.enterprisedb.com

On Thu, Dec 26, 2019 at 3:57 PM Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com> wrote:
>
> Hi All,
>
> When the following test-case is executed on master, it fails with an
> error: "ERROR: could not open relation with OID ..."
>
> -- create a test table:
> create table tab1(a int, b text);
>
> -- create a test function:
> create or replace function f1() returns void as
> $$
> declare
> var1 tab1;
> begin
> select * into var1 from tab1;
> end
> $$ language plpgsql;
>
> -- call the test function:
> select f1();
>
> -- drop the test table and re-create it:
> drop table tab1;
> create table tab1(a int, b text);
>
> -- call the test function:
> select f1();
>
> -- call the test function once again:
> select f1(); -- this fails with an error "ERROR: could not open
> relation with OID .."
>
> I'm trying to investigate this issue and will try to share my findings soon...
>
> --
> With Regards,
> Ashutosh Sharma
> EnterpriseDB:http://www.enterprisedb.com

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Julien Rouhaud 2019-12-26 12:11:53 Re: Expose lock group leader pid in pg_stat_activity
Previous Message Sergei Kornilov 2019-12-26 11:18:52 Re: Expose lock group leader pid in pg_stat_activity