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 1vyBMv-00HWC4-2s for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2026 16:16:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vyBMu-000MUQ-0m for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2026 16:16:08 +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 1vyBMt-000MTr-2m for pgsql-hackers@lists.postgresql.org; Thu, 05 Mar 2026 16:16:08 +0000 Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vyBMo-00000000xh8-3aHL for pgsql-hackers@postgresql.org; Thu, 05 Mar 2026 16:16:07 +0000 Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-660fb578f8eso3808619a12.0 for ; Thu, 05 Mar 2026 08:16:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1772727361; cv=none; d=google.com; s=arc-20240605; b=NkHzRIzFc1t1pZO/2R1oONuMry03CBGTO0SqRZYY+QRxL+VZYBoP0vROUk5O0LHTPz 2LaMaD/mxKykdkh9l9X4Y06mUEE4jF75UcZgjvuMiQAJD5hcPWWPFlQeTx61Kt6K8OjL kDQWvbe47ROxjohza3VeO/hBnyu5qKFWdlNYFWXvzemzk8FiSKzNwf93dV5YrM8A2Pc4 pXX623df4fhQygHpAz4NW/4IeoZB/GLADP1VdIrZG9Uqnn9cnwJm9cAYM+vPN7vEnUjO I8WX8FvVw4++vXyRgA0XFRT1qB8Mugd9GxJN9XCoUVlDme3jOUnK1HkH/tlEn4De7chr y02w== 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=v+XNtO2NV4Vv51xtucxU1IDO6dOK0FunWiBUV4Jf5X4=; fh=NhXgXQ3vjc0igJCwAKhNGPjLuAg3JAP1Jx+BqOM4OVQ=; b=OoKEZ9mkiR8CEKGRZEzRePe2mCgiHwGxbCYnLMC4fY3NIoUyxa+pmQGeLl2EyxkklG 0468BotV4lhRktl0JTMfm1ac8b5XMM4mpv/IwCqKRz9/AO70YTkS44XgQoC/AA69t2AL BpOn/LtxdTpNRwvWaWEvVEQaLmslIO+5LEMAiF5sxtXfR8P32bBkQPkZ5fuPTUXdbroA RSp02sL6wiAZYYBOz9EP3Am59hNQkw3/KMZUm5LbNTMDReJgJnW8T6E0tGfU0RypUAWT WQvzQE2TBYH/cVBZwLFptSGd8pt8/apzX7IBsGjfPHpqs/+od0SQmP6KqFx8zd3JQP4x WmUA==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1772727361; x=1773332161; 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=v+XNtO2NV4Vv51xtucxU1IDO6dOK0FunWiBUV4Jf5X4=; b=C8dAlowbH3xOuGYdFEMxM+E7GyRN0xT9XWzFYd4Gk6ys2WpT940RnnEjAQS961IAYi jI9C7BxtnUaPxZQ5aBL1QTjet2G9e8k8X/FFyCb5V3S/93LdbZqU4txGkEE8tNIstogR 3ZNJn9GK7vCydAwZWuafHVucKd9zylsTdrQyZ4i375NZ34Hd0NVR9U3C8HQwvlkFJjvE Sn2kFKnJTc8QZALF0bSiyNpC3DGNFHzqbSZX8ZR2o1QxusU5j+mKKjQZlIZSdQGlJutP Z0GegBX83tG59DiRP5X6uHBSJeDEggTL/MK8speQ9WGiAo+isVjV/P0/Wi5W+Ccc5c2V rEVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772727361; x=1773332161; 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=v+XNtO2NV4Vv51xtucxU1IDO6dOK0FunWiBUV4Jf5X4=; b=uDrGri1WAGN/PELFfjSIEBOso+qxF49ZoFYbsIvT/YSUdxs8MbWI+tEgj9igAhJEY1 Q4kDiI5bppbMzq4IsqDdriRGGlTrx8c1w4smirIjIhyaDMY9U9SUw/SwPkvWfol3bIy5 ZmYBJrJv1GH3eEvCOToWiFXL9/NzkcJZfIWqQgXtZf+2hr6EHO8LfLnHOiu8wa0veO0Y iDhxuJvkC6hc914K0rPnczPJolEOsmu03UaYQEdOzX1P4vfTcmNj+f7d8AqpBeRR6www phCCbzVd45F8KC7jgXYtxyYt0M2y+pbsrPFdIAPcoV3Kj9oCVFKWvItV37OJcPkTH0MF rK7A== X-Forwarded-Encrypted: i=1; AJvYcCUW1E91TdvaFFEfBtZo8RVShOlnVpBs0D4y0J+Efcme1xT0Wm7iyrYGUPGZOSWz95XTsUL2f4ZW6BJKGpd4@postgresql.org X-Gm-Message-State: AOJu0Yyc8Kmc0nJBYsOFteKGkNqqJ7MYh5JncBfXT685X4eajXYBo8kP gX3TLOMH5Sv5Vef40b6iEGX8LweQo11+byBSx1Escz851KYr0xeXOQcWjfPI0dwq3kiVDoPGfLC JXVaj7/eWXQxjNhNyWbWLSW3/AfDHQRm8R2dBHpsL X-Gm-Gg: ATEYQzzqUx39qV0b+cBp5zTMD0S/IWWElwWj1vrzwqyDPRydkoTieZsu8ZICn4G3dQ+ MfW9zkl2lA5NYrfI9NB8vMulRCYCk+IcZgJwBDtyKhn0oE3KVrVwQyhgp4uPBFSQc1M5vEPh7pt UUkZyFbU2ri5ZFhDdZAClJ0U9puze+oQ70IOKlqNkZu35XHRAzjbOAbpiUpMrISw1/Hdxr/OKJw 6arC/ihCRZz7ZwOAgy/FNey7IQrPwWqRTrqRvxGxtMjDFc2DKtitAxRj0porGEBsIAmezI67Qo/ fDN7FuPESw== X-Received: by 2002:a05:6402:2693:b0:65f:872d:ff92 with SMTP id 4fb4d7f45d1cf-6618885bbc1mr6937a12.13.1772727361082; Thu, 05 Mar 2026 08:16:01 -0800 (PST) MIME-Version: 1.0 References: <202603040943.2jvgphmddgcs@alvherre.pgsql> In-Reply-To: From: Akshay Joshi Date: Thu, 5 Mar 2026 21:45:48 +0530 X-Gm-Features: AaiRm533vgfmBi1QVGcPUn-Xd1ez2jHSFuI4hA-efjsI-oeuyh60L3sH2v1SS0I Message-ID: Subject: Re: [PATCH] Add pg_get_database_ddl() function to reconstruct CREATE DATABASE statement To: Rafia Sabih Cc: Japin Li , =?UTF-8?Q?=C3=81lvaro_Herrera?= , Euler Taveira , Amul Sul , Andrew Dunstan , Chao Li , Quan Zongliang , pgsql-hackers Content-Type: multipart/alternative; boundary="000000000000a42d36064c494006" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a42d36064c494006 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Mar 5, 2026 at 8:15=E2=80=AFPM Rafia Sabih wrote: > I like the idea for this patch and find this useful. > > I have few comments for the patch, looking at the test cases added in the > patch, it is not clear to me what is the default value for each of the > options. For example, in > Following the postgresql documentation, I created ddl_defaults.h to handle default options. This will be used across all database objects in future pg_get__ddl patches. > +-- With No Tablespace > +SELECT ddl_filter(pg_get_database_ddl('regression_utf8', 'defaults', > true, 'tablespace', false)); > + > ddl_filter > > > +------------------------------------------------------------------------= ---------------------------------------------------------------------------= ------- > + CREATE DATABASE regression_utf8 WITH OWNER =3D regress_datdba_after > ENCODING =3D 'UTF8' ALLOW_CONNECTIONS =3D true CONNECTION LIMIT =3D 123 > IS_TEMPLATE =3D false; > +(1 row) > + > owner option is omitted but the output contains the owner information. So > does it mean that the default value for each option is true? > But that doesn't seem so, because omitting pretty option, doesn't give > output in pretty, rather pretty is used only when provided. > I find this rather confusing, it is worth documenting what is the default > value for each of these options. > In my view, every database has an owner; it's a required attribute, not an optional one with a "default" value. The OWNER clause is correctly controlled only by the PG_DDL_NO_OWNER flag. Users must explicitly provide (*'owner', false/'no'/'off')* to opt out of including ownership info in the DDL. When comparing the Owner and Pretty options: by default, the Owner is included in the DDL reconstruction, whereas the Pretty option is set to false by default. In my initial patches, I used flags like --no-owner and --no-tablespace because they are very intuitive for users. However, reviewers noted that this style is unique to pg_dump and not used elsewhere. Consequently, I switched to the existing name-value pair format using VARIADIC arguments. > > Similarly, what is the expected behaviour when defaults option is not > provided, > +-- With No Owner > +SELECT ddl_filter(pg_get_database_ddl('regression_utf8', 'owner', false)= ); > + ddl_filter > +-------------------------------------------------------------- > + CREATE DATABASE regression_utf8 WITH CONNECTION LIMIT =3D 123; > +(1 row) > + > +-- With No Tablespace > +SELECT ddl_filter(pg_get_database_ddl('regression_utf8', 'defaults', > true, 'tablespace', false)); > + > ddl_filter > > > +------------------------------------------------------------------------= ---------------------------------------------------------------------------= ------- > + CREATE DATABASE regression_utf8 WITH OWNER =3D regress_datdba_after > ENCODING =3D 'UTF8' ALLOW_CONNECTIONS =3D true CONNECTION LIMIT =3D 123 > IS_TEMPLATE =3D false; > +(1 row) > Why is connection_limit present in both of these cases...? > > Another thing, what is the significance of having defaults option, becaus= e > I think that knowing non-default values could be more useful, or atleast > there should be a way to know the non-default options for the database. > The defaults option is false by default; if a user does not specify it, the reconstructed DDL only includes non-default parameters. In my opinion, we should retain this flag for users who wish to see all available parameters for easier manual editing later. While simple database objects have fewer parameters, this flag is essential for complex TABLE or FUNCTION syntax where the parameter list is extensive. > Also, the option strategy is missing in the output, is it deliberate? If > yes, why? > > On Thu, 5 Mar 2026 at 01:50, Akshay Joshi > wrote: > >> I=E2=80=99ve addressed all of your comments. >> >> Attached is the *v11 patch*, now ready for further review. >> >> On Wed, Mar 4, 2026 at 7:31=E2=80=AFPM Japin Li wr= ote: >> >>> On Wed, 04 Mar 2026 at 18:29, Akshay Joshi < >>> akshay.joshi@enterprisedb.com> wrote: >>> > Thanks for the review, Japin. I=E2=80=99ve addressed all of your comm= ents. I >>> also added a check to throw an error if an option >>> > appears more than once. >>> > >>> > Attached is the v10 patch, now ready for further review. >>> > >>> >>> Thanks for updating the patch. Here are some comments on v10. >>> >>> 1. >>> + * db_oid - OID/Name of the database for which to generate the DDL. >>> >>> Should the comment be updated? The code only accepts an OID for `db_oid= `, >>> database names are not supported. >>> >>> 2. >>> + /* Set the OWNER in the DDL if owner is not omitted */ >>> + if (OidIsValid(dbform->datdba) && !(ddl_flags & PG_DDL_NO_OWNER= )) >>> + { >>> + get_formatted_string(&buf, pretty_flags, 8, "OWNER =3D = %s", >>> + >>> quote_identifier(dbowner)); >>> + } >>> >>> `dbowner` is only needed inside this `if` =E2=80=94 how about declaring= it there >>> to >>> reduce its scope? >>> >>> 3. >>> + /* If is_with_defaults is true, then we skip default >>> encoding check */ >>> + if (is_with_defaults || >>> + >>> (pg_strcasecmp(pg_encoding_to_char(dbform->encoding), >>> + >>> DDL_DEFAULTS.DATABASE.ENCODING) !=3D 0)) >>> + { >>> + get_formatted_string(&buf, pretty_flags, 8, >>> "ENCODING =3D %s", >>> + >>> quote_literal_cstr( >>> + >>> pg_encoding_to_char(dbform->encoding))); >>> + } >>> >>> How about cache the result of `pg_encoding_to_char()` in a local >>> variable to >>> avoid calling it twice? >>> >>> -- >>> Regards, >>> Japin Li >>> ChengDu WenWu Information Technology Co., Ltd. >>> >> > > -- > Regards, > Rafia Sabih > CYBERTEC PostgreSQL International GmbH > --000000000000a42d36064c494006 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Thu, Mar 5, = 2026 at 8:15=E2=80=AFPM Rafia Sabih <rafia.pghackers@gmail.com> wrote:
I like the idea fo= r this patch and find this useful.

I have few comm= ents for the patch, looking at the test cases added in the patch, it is not= clear to me what is the default=C2=A0value for each of the options. For ex= ample, in

=C2=A0 =C2=A0Following the postg= resql documentation, I created=C2=A0ddl_defaults.h=C2=A0to han= dle default options. This will be used across all database objects in futur= e=C2=A0pg_get_<object>_ddl=C2=A0patches.
=C2=A0
=
+--= With No Tablespace
+SELECT ddl_filter(pg_get_database_ddl('regressi= on_utf8', 'defaults', true, 'tablespace', false));
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ddl_filter =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0+------------------------------------------------------------------------= ---------------------------------------------------------------------------= -------
+ CREATE DATABASE regression_utf8 WITH OWNER =3D regress_datdba_= after ENCODING =3D 'UTF8' ALLOW_CONNECTIONS =3D true CONNECTION LIM= IT =3D 123 IS_TEMPLATE =3D false;
+(1 row)
+
owner option i= s omitted but the=C2=A0output contains the owner information. So does it me= an that the default value for each option is true?
But that doesn= 't seem so,=C2=A0because omitting pretty option, doesn't give outpu= t in pretty, rather pretty is used only when provided.
I find thi= s rather confusing, it is worth documenting what is the default value for e= ach of these options.

=C2=A0 =C2=A0 In my = view, every database has an owner; it's a required attribute, not an op= tional one with a "default" value.=C2=A0The OWNER clause is corre= ctly controlled only by the PG_DDL_NO_OWNER flag. Users must explicitly pro= vide ('owner', false/'no'/'off')=C2=A0to opt= out of including ownership info in the DDL.=C2=A0When comparing the Owner = and Pretty options: by default, the Owner is included in the DDL reconstruc= tion, whereas the Pretty option is set to false by default.

=C2=A0 = =C2=A0=C2=A0In my initial patches, I used flags like --no-owner and --no-ta= blespace because they are very intuitive for users. However, reviewers note= d that this style is unique to pg_dump and not used elsewhere. Consequently= , I switched to the existing name-value pair format using VARIADIC argument= s.
=

Similarly, what is the expected behaviour when defaults= option is not provided,
+-- With No Owner
+SELECT ddl_filter(= pg_get_database_ddl('regression_utf8', 'owner', false));+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0ddl_filter =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0
+----------------------= ----------------------------------------
+ CREATE DATABASE regression_ut= f8 WITH CONNECTION LIMIT =3D 123;
+(1 row)
+
+-- With No Tablespac= e
+SELECT ddl_filter(pg_get_database_ddl('regression_utf8', '= ;defaults', true, 'tablespace', false));
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0ddl_filter =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0
+---------------= ---------------------------------------------------------------------------= ----------------------------------------------------------------
+ CREAT= E DATABASE regression_utf8 WITH OWNER =3D regress_datdba_after ENCODING =3D= 'UTF8' ALLOW_CONNECTIONS =3D true CONNECTION LIMIT =3D 123 IS_TEMP= LATE =3D false;
+(1 row)
Why is connection_limit present in bo= th of these cases...?

Another thing, what is the s= ignificance of having defaults option, because I think that knowing non-def= ault values could be more useful, or atleast there should be a way to know= =C2=A0 the non-default options for the database.

=C2=A0 =C2=A0 The defaults option is false by default; if a user doe= s not specify it, the reconstructed DDL only includes non-default parameter= s. In my opinion, we should retain this flag for users who wish to see all = available parameters for easier manual editing later. While simple database= objects have fewer parameters, this flag is essential for complex TABLE or= FUNCTION syntax where the parameter list is extensive.
=C2=A0 =C2=A0 = =C2=A0
Also, the option strategy is missing in the output, is it delibera= te? If yes, why?=C2=A0

On Thu, 5 Mar 2026 at 01:50, Akshay Joshi <akshay.joshi@enterpri= sedb.com> wrote:

I=E2=80=99ve addressed all of your comments.

Attached is the=C2=A0v11 patch, now ready for further review.


On Wed, Mar 4, 2026 at 7:31=E2=80=AFPM Japin Li <japinli@hotmail.com> wrote:
On Wed, 04 Mar 2026 a= t 18:29, Akshay Joshi <akshay.joshi@enterprisedb.com> wrote:
> Thanks for the review, Japin. I=E2=80=99ve addressed all of your comme= nts. I also added a check to throw an error if an option
> appears more than once.
>
> Attached is the v10 patch, now ready for further review.
>

Thanks for updating the patch.=C2=A0 Here are some comments on v10.

1.
+ * db_oid - OID/Name of the database for which to generate the DDL.

Should the comment be updated? The code only accepts an OID for `db_oid`, database names are not supported.

2.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Set the OWNER in the DDL if owner is not omi= tted */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (OidIsValid(dbform->datdba) && !(= ddl_flags & PG_DDL_NO_OWNER))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0get_formatted_strin= g(&buf, pretty_flags, 8, "OWNER =3D %s",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 quote_identifier(dbowner))= ;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}

`dbowner` is only needed inside this `if` =E2=80=94 how about declaring it = there to
reduce its scope?

3.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* If is_with_defau= lts is true, then we skip default encoding check */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (is_with_default= s ||
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(pg_strcasecmp(pg_encoding_to_char(dbform->encoding),
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 DDL_DEFAULTS.DATABASE.ENCODING) !=3D 0))
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0get_formatted_string(&buf, pretty_flags, 8, "ENCODING = =3D %s",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 quote_literal_cstr(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pg_enc= oding_to_char(dbform->encoding)));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}

How about cache the result of `pg_encoding_to_char()` in a local variable t= o
avoid calling it twice?

--
Regards,
Japin Li
ChengDu WenWu Information Technology Co., Ltd.


--
Regards,
Rafia Sabih
CYBERTEC PostgreSQL = International GmbH
--000000000000a42d36064c494006--