Thread
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add pg_get_database_ddl() function
- a4f774cf1c7e 19 (unreleased) cited
-
[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 -
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 -
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 -
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