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 1wbYZu-002f55-17 for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 06:56:18 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wbYYt-004oKg-37 for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 06:55:15 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wbYYt-004oKY-1k for pgsql-hackers@lists.postgresql.org; Mon, 22 Jun 2026 06:55:15 +0000 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wbYYr-00000001Y6p-3ehS for pgsql-hackers@lists.postgresql.org; Mon, 22 Jun 2026 06:55:14 +0000 Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-2c6bdb8a8bdso20259115ad.1 for ; Sun, 21 Jun 2026 23:55:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782111312; x=1782716112; darn=lists.postgresql.org; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=4Q7OSCaRwOLPkFt3Vwj9sIapfF5kpcAA3O39l7DwrUI=; b=WwzY5xY7v9GySIBhG5X/p+7L/P0IYbT3b8xyeRKTU9cMFO/XvrAV10Dl8dGJ+KroXE FpofgCmVE4c3Cut63uSJ4adUE3EOCKyrgxFvBMqfRUhEsXQUfTzyF7T8W1jFdpWt+j90 Ld50uXXgAJgI3H5loGdHe48uL1N6tTjAu0eTyKQ64xRLw7iJN7U0G+A8CF9ONClXngZ7 rm7BhOnVRjbhTRiuJYc8TFd+Jjx7JZxAeSDSL3oxnI8wgdHaFez7l8B2aMgAbN2QjBIf AJfG+GIxDFEvzxmBD5qltcfuLfVGj3qDPr2aM3rSWjaWzLfwXvXK5JiNDhfDjPb2KN5J LJRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782111312; x=1782716112; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=4Q7OSCaRwOLPkFt3Vwj9sIapfF5kpcAA3O39l7DwrUI=; b=ant0i5EC0AswbmPetVWBkJsMawnLBixeK/+1VNRfhLimgEqwi+RL/d3s97HlO7vARz XYJHXl14e7qMnC5r4KqWyn1RRg36bl+mWAmGLGkNkznEoR51SBTuq3V0quQkus/IjFk5 cHZwnc1d0MK1sNihKN483A821cAFnpia2OTwS//+2xkLBRzw2oM9nCQJB+bqB7aT1QW5 Ne/4Ir60n2H2z5DkZJ3XSTUGEFT/QqueS18bj3h1UZ4Brmd2OSNxSXGNtFG/pmzfx8bG m7cMtIbr/4vLwti41rOEcF+vINFyEslVLtazmajscfzwSqoQqQenm1btJQmKVcN5fJub vVvA== X-Forwarded-Encrypted: i=1; AHgh+RoWsNZeNVjwWl9SjxKBuq5eSKW6ftMclIgQi8mvBu3xP8TFAqXBtsebKqT+XBfIbTfvuFyZ+SvVpjohm19P@lists.postgresql.org X-Gm-Message-State: AOJu0Yyix53VytbI12ewHD31QD37VQHhwog1aNGHLLL6+PBcbZArTXOk fmrfQc5lK1HT+y3pMxVdUf52zmGwmmZiM40sCqi6IRgWm6eqngUsEJB2 X-Gm-Gg: AfdE7cl2K0lygM4rTTYSOTv/Ng/memetriQvKdAHuO/m0JZH9rl4DpOvZA1ljqouAGE O0hV8yp9xfj3hq8oDCvTS7tE0UomHrPco4vQQT8K1QK4E3iXVfULaByZzIfTM2gcNKtZ49n7CLH EGVsCFZ7TXBeclPNBgnYUdY+qTGCtZQc2Pt+vhzB0N9U0VBcYUksaZLYA6W3NXh8pIpXgBA1Jwz nk3m7yIYDurpBZEaxW3tdFWt1xTwA84YAByTVeOdmwmDNrvMOWrHqrKmP+xtNAJ9OFqHIvoGQEe hMQddGDjwf4vjyMjGbksca0mwZ0Ios57pP0VfkFo+9I3qa2Y6gUvPUOf0eXUgbiWZ6oW24H7MD3 KVxGWxxd3tvtOO9Vk9lPRE+V7NLAdUE0fcxaUnqoL+OLrjdyotDFL4ybzP7nD+SlPc1tdFYS75c V4R/RFlmHbgmPAi98qJGh5Tg== X-Received: by 2002:a17:902:e805:b0:2b2:4b4e:e4d2 with SMTP id d9443c01a7336-2c725b96249mr122806145ad.15.1782111312475; Sun, 21 Jun 2026 23:55:12 -0700 (PDT) Received: from smtpclient.apple ([185.135.79.161]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c7436d6c16sm69093605ad.23.2026.06.21.23.55.09 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 21 Jun 2026 23:55:11 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.600.51.1.1\)) Subject: Re: [PATCH] Add pg_get_table_ddl() to reconstruct CREATE TABLE statements From: Chao Li In-Reply-To: Date: Mon, 22 Jun 2026 14:54:35 +0800 Cc: Zsolt Parragi , pgsql-hackers@lists.postgresql.org Content-Transfer-Encoding: quoted-printable Message-Id: <983C7B03-D9C3-4F15-8913-7616EC5E6414@gmail.com> References: To: Akshay Joshi X-Mailer: Apple Mail (2.3864.600.51.1.1) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > On Jun 22, 2026, at 14:26, Akshay Joshi = wrote: >=20 > Thanks for the review; you're right, `includes_foreign_keys=3Dfalse` = on its own is a half-measure. Re-running with the default to add FKs = back collides with the existing CREATE TABLE, UNIQUE indexes, etc. >=20 > I've added an only_foreign_keys option (boolean, default false) as the = natural complement of includes_foreign_keys=3Dfalse. When set to true, = the function emits only the ALTER TABLE ... ADD CONSTRAINT ... FOREIGN = KEY statements and suppresses everything else (CREATE TABLE, owner, = indexes, non-FK constraints, rules, statistics, replica identity, RLS = toggles). Partition-child recursion still runs so child FKs are reached = too. Combining `only_foreign_keys=3Dtrue` with = `includes_foreign_keys=3Dfalse` is rejected upfront since it would = produce no output. >=20 > The documentation paragraph for `includes_foreign_keys` now directs = users to `only_foreign_keys` as the intended second pass. Regression = coverage adds three cases: the FK-only emission for your cons example, = the zero-row result for a table without FKs, and the error path.=20 >=20 > The v8 patch is ready for review. >=20 > On Sat, Jun 20, 2026 at 1:15=E2=80=AFAM Zsolt Parragi = wrote: > The previous features all look good to me, I only have one question > for the new flag. >=20 > > Calling > > pg_get_table_ddl(t, 'includes_foreign_keys', 'false') now emits = everything > > except FOREIGN KEY constraints. This covers the multi-tenant clone > > workflow: create tables first without cross-table references, then = re-run > > with the default to add the constraints once all targets exist. >=20 > I think this feature needs a bit more documentation, an > "only_foreign_keys" flag, or both. >=20 > CREATE TABLE refd (id int PRIMARY KEY); > CREATE TABLE cons (a int CHECK(a>0), b int UNIQUE, c int REFERENCES = refd(id)); >=20 > -- pass 1: running without foreign keys > SELECT * FROM = pg_get_table_ddl('cons','includes_foreign_keys','false'); > -- execute everything >=20 > -- loading data >=20 > -- pass 2: running with everything > SELECT * FROM pg_get_table_ddl('cons','includes_foreign_keys','true'); > -- ERROR: relation "cons" already exists (and the unique constraint > also collides) >=20 > I could do a "grep FOREIGN KEY" before executing (unless it's a tricky > schema where that phrase appears elsewhere), or since psql continues > on error, it will simply work if I accept a significant error noise, > but then the documentation should be clear about this limitation. > Following the documented approach and getting a bunch of unexpected > errors could be confusing for users. >=20 >=20 > I have a comment, or maybe a question: ``` +{ oid =3D> '8215', descr =3D> 'get DDL to recreate a table', + proname =3D> 'pg_get_table_ddl', prorows =3D> '50', provariadic =3D> = 'text', + proisstrict =3D> 'f', proretset =3D> 't', provolatile =3D> 's', = proparallel =3D> 'r', + pronargdefaults =3D> '1', prorettype =3D> 'text', + proargtypes =3D> 'regclass text', proallargtypes =3D> = '{regclass,text}', + proargmodes =3D> '{i,v}', proargdefaults =3D> '{NULL}', + prosrc =3D> 'pg_get_table_ddl' }, ``` Since provariadic is text, I wonder if proallargtypes should be = {regclass,_text}, with _text meaning an array of text. I=E2=80=99m asking because I have had this suspicion for some time. I = saw a few other procs using the same pattern, for example: ``` { oid =3D> '6501', descr =3D> 'get DDL to recreate a role', proname =3D> 'pg_get_role_ddl', prorows =3D> '10', provariadic =3D> = 'text', proisstrict =3D> 'f', proretset =3D> 't', provolatile =3D> 's', pronargdefaults =3D> '1', prorettype =3D> 'text', proargtypes =3D> = 'regrole text', proallargtypes =3D> '{regrole,text}', proargmodes =3D> '{i,v}', proargdefaults =3D> '{NULL}', prosrc =3D> 'pg_get_role_ddl' }, ``` But for jsonb_delete etc procs, _text is used: ``` { oid =3D> '3343', proname =3D> 'jsonb_delete', provariadic =3D> 'text', prorettype =3D> = 'jsonb', proargtypes =3D> 'jsonb _text', proallargtypes =3D> '{jsonb,_text}', proargmodes =3D> '{i,v}', proargnames =3D> '{from_json,path_elems}', prosrc =3D> 'jsonb_delete_array' }, ``` So I wonder whether =E2=80=9Ctext=E2=80=9D rather than =E2=80=9C_text" = is intentionally used in proallargtypes, or if this was just never = noticed. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/