postgres-github.git / summary / log / commit / refs

commit    2fbb21170e9053720c2c374b21eb650a22b8aaea
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:     Wed May 27 15:35:58 2026 +0000

    Avoid orphaned objects dependencies
    
    Concurrent DDL can leave behind objects referencing other objects that
    no longer exist. This can happen if an object is dropped, while a new
    object that depends on it is created concurrently. For example:
    
    session 1: BEGIN; CREATE FUNCTION myschema.myfunc() ...;
    session 2: DROP SCHEMA myschema;
    session 1: COMMIT;
    
    DROP SCHEMA does check that there are no objects dependending on the
    schema being dropped, but it does not see objects being concurrently
    created by other sessions. Even if it did, this scenario would still
    fail:
    
    session 1: BEGIN: DROP SCHEMA myschema;
    session 2: CREATE FUNCTION myschema.myfunc() ...;
    session 1: COMMIT;
    
    When the DROP SCHEMA runs, the schema was empty, but the new function
    is created in it before the dropping transaction completes. The CREATE
    FUNCTION does not see that the schema is concurrently being dropped.
    
    In both of these scenarios, the function is left behind in the schema
    that no longer exists.
    
    To fix, acquire AccessShareLock on all referenced objects when
    recording dependencies. This conflicts with the AccessExclusiveLock
    taken by DROP, preventing the race. After acquiring the lock, verify
    that the object still exists, and if it was dropped concurrently,
    report an error. We already had such a mechanism for shared
    dependencies, but for some reason we didn't do it for in-database
    dependendies.
    
    Ideally the locks would be acquired much earlier when creating a new
    object, but that will require modifying a lot of callers. This check
    while recording the dependency is a nice wholesale protection, and
    even if we change all the CREATE commands to acquire locks earlier,
    it's still good to have this as a backstop to catch any cases where we
    forgot to do so.
    
    The patch adds a few tests for some cases that left behind orphaned
    objects before this. It also adds a test for roles, which already had
    such protection, although that test is partially disabled because the
    error message includes an OID which is not predictable.
    
    Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
    Reviewed-by: Heikki Linnakangas <heikki.linnakangas@iki.fi>
    Discussion: https://postgr.es/m/ZiYjn0eVc7pxVY45@ip-10-97-1-34.eu-west-3.compute.internal
    Backpatch-through: 14

[parent: fd93ee100830]