Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCGna-001ojV-00 for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 12:53:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wCGnX-006lTl-0W for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Apr 2026 12:53:52 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCGnW-006lTc-2i for pgsql-hackers@lists.postgresql.org; Mon, 13 Apr 2026 12:53:51 +0000 Received: from mail-yw1-x1134.google.com ([2607:f8b0:4864:20::1134]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wCGnV-00000000ptu-25Qh for pgsql-hackers@postgresql.org; Mon, 13 Apr 2026 12:53:51 +0000 Received: by mail-yw1-x1134.google.com with SMTP id 00721157ae682-79885f4a8ffso42178857b3.3 for ; Mon, 13 Apr 2026 05:53:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776084827; cv=none; d=google.com; s=arc-20240605; b=ljlScKaMfWw7JTsR4RPNkCkhWBtng2M9RLeuIwbzOCyboDkD0aZihlEzQ3VrEDYwdR q/4m4+tBqg38fKTlFPOW8Vmwmh+vSGWXPpF7E82zBNLhgISYhUxp4N/l8JLu9CrBhMot zWaicyYks0lhF0WqPHYqQTHG7/AnpTyFrzXjRFdnTIIIWVPIKOddsbV1chWL/5FbaPVH qCXeuRgksOtlMPT66S/LLC7YsvN/+0veWlPOlZmLzP0gv0SXrvtHy8r/w4ipFYStWgRn 89b2eHHjgeGTlDMbDeQfXgO4BbTvPhAgnChFpR9KgJqfNy7EjBsmXMs7/PA8Nwy3UtE5 +EzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=ZKuRTRZey3SKLE9azNpyy4i+EuHIkLmyrrCne05Hv3U=; fh=gJGSDN8sONSZriWDmBLejQtlcQChoyS0DXcfdd5oMHs=; b=IOUo+kdV4+64y6xUIVx3iWkoUjst308YT4g9wD72AmfxUuXCp0ojNAGhN0KGdSVPw0 ECS+Z7//jsf5jzSJ61Nl+QQ6mrz2DP8B+Cw8iQoJyRk8vPIHgUxrjq98EiJh8C0cGD8L 6SdkNW5afxk8oQLMbSmdqwf14Tt23uOZRqb1EDOrQjVkyc7/XHRyx/DRGFqDyN4smdRu 2TncFU3CarQrCTa4aCKxsV51hPChkg4bbmL2PNZWWvsMyLNMHrxXVF699xihsPhclaJy CLTOIGv1KdIrB2X3TJlCZZ9D8cQxKlkTdttEUsRgNqN5kEjzaYKR4NEaGehe+KV1qAXq aVrQ==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776084827; x=1776689627; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=ZKuRTRZey3SKLE9azNpyy4i+EuHIkLmyrrCne05Hv3U=; b=IiXCc7O+B5J/mDaEW3XodZeVdQC/xDjLXaIln8q1po7bEr1nG8qn4+3wWVJkB4y5HZ DlaIN1DQPuUBrb8HO+Yo/Yy4kHyUSoWUcKBgiTYZ2ddYrujF+1iszimZ41uE1R9vLhZY kj8fyYZiyiJJBXjNgRO+nhG4gLBCGmBpE4jAJ6G62b+Q6ynnqfoNNofE9WKqfGhdObrn ZtEN02zsnMxYLUl4fnA4avKLsyFTBE6l9KCpiHpWINgtmcmUcwAbAfAHJiKY+DiKNpKT bfsqxvietYw//rVO22Qv6LkFj8XTBlU8/yALRUnf98L78eN9XGrFTBhMhgSlt2OjVoTd eVKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776084827; x=1776689627; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ZKuRTRZey3SKLE9azNpyy4i+EuHIkLmyrrCne05Hv3U=; b=jCfpb5UWdJIRPcgZk1IEyBQkPN61mmgHKLTkFLDy/DcqPggQe4FblwD3rwD+TwIz+L U/6E14B8DI+Rw4dt+MaeQikjQkWiJEBMKscrl2IxyRBaq93wLkpUBQ2krl2J52k03prC WjtXr/5pOjKDMF/EfZ/sXAJwhd7jxM8TLYVPy97PnEsuJlThXrzwwJMYcwuWhTBQNhYa ciJ2IXlxxVKmuNQjKk/uB7FhZO+XLO1O1LkLi4Rtly/83i54H7rghcaIxKfgvXb6LeoQ 3w3przRFlXghbAfuJRPfubA0+FUEC8wVkt3f2KFDc8/cg8xOi+KDSDdd0Wi7xkmvQP2C I01w== X-Gm-Message-State: AOJu0YwkSTjgh2Dx5DV52FHFIL5eMd14OphTgv2Y9cO1NRHsBtnnEP2u EdwaWQhYo2/8IF4JZ9LQ57e4Ti9mI2TRk0saa+ZeKpvfOsanx0YAmqssWW60yrlrwfPuT8EGPZ9 LaeiugsTcHTYtYf2I0xWMMjN48Kak9Gs= X-Gm-Gg: AeBDiev9UObexpG3FyYLQbHRuEfcSMnWaGsSqBewTzoM8YPJuOaulV3fv3i/xuctKh3 Aplpn8E8oisqvHxv7tBQGg6FTgQYhHZg6Qr/J0dDiRI7mgpBspnjAFeSaTwxNDKEGPFwOn6P0na p9d7U5Z43Cb1An2cm0mv1JqyFeqIkYW01q82KZnCGMy3jB+K/dB92WwKQyqz1eCJH07O6Lu7o7K g4ajIafL+Fu6mO3ZO9VkAuT8REs+Qxkh9DLTHuJFrGC1AkXsQhc0F4m5rjAmZ+/V213zDywnKR7 kAeqyw== X-Received: by 2002:a05:690c:6882:b0:79a:1b3a:e91f with SMTP id 00721157ae682-7af7272ca84mr137639777b3.52.1776084827322; Mon, 13 Apr 2026 05:53:47 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ayush Tiwari Date: Mon, 13 Apr 2026 18:23:35 +0530 X-Gm-Features: AQROBzDFoJlPEZ8ohMODbRxUYuwfSkx74yZ6pLdUgZUYFoytW0NQRMFDG3hLvlA Message-ID: Subject: Re: [PATCH] Fix NULL dereference in pg_get_database_ddl() To: David Rowley Cc: pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="000000000000393e74064f56f9c3" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000393e74064f56f9c3 Content-Type: text/plain; charset="UTF-8" Hi, On Mon, 13 Apr 2026 at 15:02, David Rowley wrote: > On Sat, 11 Apr 2026 at 01:58, Ayush Tiwari > 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 --000000000000393e74064f56f9c3 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Mon, 13 Apr 2= 026 at 15:02, David Rowley <dgro= wleyml@gmail.com> wrote:
On Sat, 11 Apr 2026 at 01:58, Ayush Tiwari <ayushtiwari.slg01@gmai= l.com> wrote:
> Deterministic reproduction:
>
> CREATE DATABASE regression_testdb;
> SET allow_system_table_mods =3D on;
> UPDATE pg_database
>=C2=A0 SET dattablespace =3D 99999
>=C2=A0 WHERE datname =3D '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().=C2=A0 In that case, pg_get_database_ddl() simply omit= s 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.postgresq= l.org/message-id/19383-e6b60ec2a4fce5b0@postgresql.org
[2] https://www.postgresql.o= rg/message-id/1538113.1768921841%40sss.pgh.pa.us

<= /div>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_da= tabase_ddl_internal() reads pg_database.dattablespace, and then a
concur= rent change makes get_tablespace_name() return NULL before the second
lo= okup. 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 a= re 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 com= mit a state where pg_database still points at a
vanished tablespace row = through supported SQL, because the drop fails while the
database directo= ry 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 cite= d 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 i= ssue around the missing database/tablespace bookkeeping.

Thanks= again for the push to investigate it more carefully.=C2=A0

Regards,=
Ayush
--000000000000393e74064f56f9c3--