Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Add pg_get_database_ddl() function

  1. [PATCH] Fix NULL dereference in pg_get_database_ddl()

    Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-04-10T13:57:58Z

    Hi,
    
    pg_get_database_ddl_internal() can dereference a NULL pointer when
    pg_database.dattablespace points to a tablespace OID that no longer
    exists.
    
    The immediate issue is that get_tablespace_name() may return NULL, but
    the result is passed directly to pg_strcasecmp():
    
    spcname = get_tablespace_name(dbform->dattablespace);
    if (pg_strcasecmp(spcname, "pg_default") != 0)
    ...
    
    That leads to a backend crash.  I reproduced it on current master as a
    SIGSEGV with crash recovery.
    
    This function was introduced by commit a4f774cf1c7.
    
    Deterministic reproduction:
    
    CREATE DATABASE regression_testdb;
    SET allow_system_table_mods = on;
    UPDATE pg_database
     SET dattablespace = 99999
     WHERE datname = 'regression_testdb';
    RESET allow_system_table_mods;
    
    SELECT * FROM pg_get_database_ddl('regression_testdb');
    
    The attached patch fixes this by checking for NULL before calling
    pg_strcasecmp().  In that case, pg_get_database_ddl() simply omits the
    TABLESPACE clause.
    
    I also added a regression test in database_ddl.sql that exercises this
    case by setting dattablespace to a non-existent OID and verifying that
    the function returns successfully.
    
    Patch attached. Please review and let me know if it needs any edits. Thanks!
    
    Regards,
    Ayush Tiwari
    
  2. Re: [PATCH] Fix NULL dereference in pg_get_database_ddl()

    Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-04-10T14:13:10Z

    On Fri, 10 Apr 2026 at 19:27, Ayush Tiwari <ayushtiwari.slg01@gmail.com>
    wrote:
    
    > Hi,
    >
    > pg_get_database_ddl_internal() can dereference a NULL pointer when
    > pg_database.dattablespace points to a tablespace OID that no longer
    > exists.
    >
    > The immediate issue is that get_tablespace_name() may return NULL, but
    > the result is passed directly to pg_strcasecmp():
    >
    > spcname = get_tablespace_name(dbform->dattablespace);
    > if (pg_strcasecmp(spcname, "pg_default") != 0)
    > ...
    >
    > That leads to a backend crash.  I reproduced it on current master as a
    > SIGSEGV with crash recovery.
    >
    > This function was introduced by commit a4f774cf1c7.
    >
    > Deterministic reproduction:
    >
    > CREATE DATABASE regression_testdb;
    > SET allow_system_table_mods = on;
    > UPDATE pg_database
    >  SET dattablespace = 99999
    >  WHERE datname = 'regression_testdb';
    > RESET allow_system_table_mods;
    >
    > SELECT * FROM pg_get_database_ddl('regression_testdb');
    >
    > The attached patch fixes this by checking for NULL before calling
    > pg_strcasecmp().  In that case, pg_get_database_ddl() simply omits the
    > TABLESPACE clause.
    >
    > I also added a regression test in database_ddl.sql that exercises this
    > case by setting dattablespace to a non-existent OID and verifying that
    > the function returns successfully.
    >
    > Patch attached. Please review and let me know if it needs any edits.
    > Thanks!
    >
    > Regards,
    > Ayush Tiwari
    >
    
    Re-attaching patch without trailing white-space
    
    Regards,
    Ayush
    
  3. Re: [PATCH] Fix NULL dereference in pg_get_database_ddl()

    David Rowley <dgrowleyml@gmail.com> — 2026-04-13T09:32:32Z

    On Sat, 11 Apr 2026 at 01:58, Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote:
    > Deterministic reproduction:
    >
    > CREATE DATABASE regression_testdb;
    > SET allow_system_table_mods = on;
    > UPDATE pg_database
    >  SET dattablespace = 99999
    >  WHERE datname = 'regression_testdb';
    > RESET allow_system_table_mods;
    >
    > SELECT * FROM pg_get_database_ddl('regression_testdb');
    >
    > The attached patch fixes this by checking for NULL before calling
    > pg_strcasecmp().  In that case, pg_get_database_ddl() simply omits the
    > TABLESPACE clause.
    
    Can you explain why this method of self-inflicted catalogue corruption
    is any more important than any of the just-about-infinite other ways
    there are of causing issues by manually updating the catalogue tables?
    
    The typical response to this sort of thing can be seen in the thread
    in [1], in particular, the response in [2].
    
    David
    
    [1] https://www.postgresql.org/message-id/19383-e6b60ec2a4fce5b0@postgresql.org
    [2] https://www.postgresql.org/message-id/1538113.1768921841%40sss.pgh.pa.us
    
    
    
    
  4. Re: [PATCH] Fix NULL dereference in pg_get_database_ddl()

    Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-04-13T12:53:35Z

    Hi,
    
    On Mon, 13 Apr 2026 at 15:02, David Rowley <dgrowleyml@gmail.com> wrote:
    
    > On Sat, 11 Apr 2026 at 01:58, Ayush Tiwari <ayushtiwari.slg01@gmail.com>
    > wrote:
    > > Deterministic reproduction:
    > >
    > > CREATE DATABASE regression_testdb;
    > > SET allow_system_table_mods = on;
    > > UPDATE pg_database
    > >  SET dattablespace = 99999
    > >  WHERE datname = 'regression_testdb';
    > > RESET allow_system_table_mods;
    > >
    > > SELECT * FROM pg_get_database_ddl('regression_testdb');
    > >
    > > The attached patch fixes this by checking for NULL before calling
    > > pg_strcasecmp().  In that case, pg_get_database_ddl() simply omits the
    > > TABLESPACE clause.
    >
    > Can you explain why this method of self-inflicted catalogue corruption
    > is any more important than any of the just-about-infinite other ways
    > there are of causing issues by manually updating the catalogue tables?
    >
    > The typical response to this sort of thing can be seen in the thread
    > in [1], in particular, the response in [2].
    >
    > David
    >
    > [1]
    > https://www.postgresql.org/message-id/19383-e6b60ec2a4fce5b0@postgresql.org
    > [2]
    > https://www.postgresql.org/message-id/1538113.1768921841%40sss.pgh.pa.us
    
    
    Thanks for the review.
    
    I dug into this further and I don't think I can support the patch as a real
    bug fix.
    
    My original thought was that there might be a supported concurrent-DDL path
    where
    pg_get_database_ddl_internal() reads pg_database.dattablespace, and then a
    concurrent change makes get_tablespace_name() return NULL before the second
    lookup. I tried to reproduce that by widening the window and testing
    ALTER DATABASE ... SET TABLESPACE together with DROP TABLESPACE, but I
    could not
    make it happen.
    
    The reason seems to be that both catalog reads are governed by the same
    statement-level CatalogSnapshot, so the function continues to see a
    consistent
    catalog view for the duration of the call. On the other side, DROP
    TABLESPACE
    also doesn't appear able to commit a state where pg_database still points
    at a
    vanished tablespace row through supported SQL, because the drop fails while
    the
    database directory is still present.
    
    So at this point the remaining crash case seems to require a broken catalog
    state,
    which puts this in the same bucket as the precedent you cited rather than a
    supported-path bug.
    
    Given that, I don't think this patch is worth pursuing further in its
    current
    form. I'll drop it here unless I find a supported reproducer or a different,
    stronger issue around the missing database/tablespace bookkeeping.
    
    Thanks again for the push to investigate it more carefully.
    
    Regards,
    Ayush