Re: pg_get_expr locking

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Peter Eisentraut <peter@eisentraut.org>
Cc: pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2024-02-08T20:20:59Z
Lists: pgsql-hackers

Attachments

I wrote:
> Peter Eisentraut <peter@eisentraut.org> writes:
>> I think the situation is that one test (domain) runs pg_get_expr as part 
>> of an information_schema view, while at the same time another test 
>> (alter_table) drops a table that the pg_get_expr is just processing.

> The test case that's failing is, IIUC,

> +SELECT * FROM information_schema.domain_constraints
> +  WHERE domain_name IN ('con', 'dom', 'pos_int', 'things')
> +  ORDER BY constraint_name;

Oh, scratch that: there are two confusingly lookalike queries
in the patch.  The one that is failing is

SELECT * FROM information_schema.check_constraints
  WHERE (constraint_schema, constraint_name)
        IN (SELECT constraint_schema, constraint_name
            FROM information_schema.domain_constraints
            WHERE domain_name IN ('con', 'dom', 'pos_int', 'things'))
  ORDER BY constraint_name;

and we have trouble because the evaluation of pg_get_expr in
check_constraints is done before the semijoin that would restrict
it to just the desired objects.

After looking at the code I'm less worried about the
permissions-checking angle than I was before, because I see
that pg_get_expr already takes a transient AccessShareLock
on the rel, down inside set_relation_column_names.  This is
not ideal from a permissions standpoint perhaps, but it's
probably OK considering we've done that for a long time.
We just need to hold that lock a little while longer.

I propose the attached as a reasonably localized fix.
We could imagine a more aggressive refactoring that would
allow passing down the Relation instead of re-opening it
in set_relation_column_names, but I doubt it's worth the
trouble.

			regards, tom lane

Commits

  1. Remove race condition in pg_get_expr().