Re: [PATCH] Add pg_get_table_ddl() to reconstruct CREATE TABLE statements

Akshay Joshi <akshay.joshi@enterprisedb.com>

From: Akshay Joshi <akshay.joshi@enterprisedb.com>
To: Zsolt Parragi <zsolt.parragi@percona.com>
Cc: pgsql-hackers@lists.postgresql.org
Date: 2026-06-10T11:24:22Z
Lists: pgsql-hackers

Attachments

Thanks for the review. I have fixed all the issues you mentioned.

Because this is a major restructuring of the DDL function involving
multiple child elements and complex syntaxes, some edge cases might still
pop up, though I have tried to cover as much as possible.

The v4 patch is ready for your review.

On Wed, Jun 10, 2026 at 12:47 AM Zsolt Parragi <zsolt.parragi@percona.com>
wrote:

> Thanks, I can confirm that the previous bugs were fixed, however the
> bugfixes also introduce a new issue, where inherited not null
> constraints are missing:
>
> CREATE TABLE par (a int);
> CREATE TABLE ch (b int) INHERITS (par);
> ALTER TABLE ch ADD CONSTRAINT my_nn NOT NULL a;
> SELECT * FROM pg_get_table_ddl('ch','owner','false');
> --  CREATE TABLE public.ch ( b integer) INHERITS (public.par);
>
> The schema_qualified => false part also doesn't work as described:
>
> +        <command>CREATE STATISTICS</command> statement.  References to
> +        objects in the same schema as the target table (inheritance
> +        parents, partition parents, identity sequences, and any
> +        same-schema object the deparse helpers happen to mention) are
> +        also emitted unqualified, so the script can be replayed under a
> +        different <varname>search_path</varname> to recreate the table
> +        in another schema.
>
> but:
>
> CREATE SCHEMA s1;
> CREATE SEQUENCE s1.myseq;
> CREATE FUNCTION s1.f(int) RETURNS int LANGUAGE sql IMMUTABLE AS 'SELECT
> $1';
> CREATE TABLE s1.t (
>     id  int DEFAULT nextval('s1.myseq'),
>     val int,
>     CONSTRAINT chk CHECK (s1.f(val) > 0)
> );
> SELECT * FROM pg_get_table_ddl('s1.t', 'owner','false',
> 'schema_qualified','false');
> --  CREATE TABLE t ( id integer DEFAULT nextval('s1.myseq'::regclass),
> val integer, CONSTRAINT chk CHECK ((s1.f(val) > 0)));
>
> s1 appears twice in the output.
>
> It also has an issue with strings containing the schema:
>
> CREATE SCHEMA myschema;
> CREATE TABLE myschema.p (id int, note text) PARTITION BY RANGE (id);
> CREATE TABLE myschema.pc PARTITION OF myschema.p
>     (CONSTRAINT chk CHECK (note <> 'myschema.secret')) FOR VALUES FROM
> (0) TO (100);
> SELECT * FROM pg_get_table_ddl('myschema.pc', 'owner','false',
> 'schema_qualified','false');
> -- CREATE TABLE pc PARTITION OF p FOR VALUES FROM (0) TO (100);
> -- ALTER TABLE pc ADD CONSTRAINT chk CHECK ((note <> 'secret'::text));
>
>
>