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 1vL9al-005qiK-0J for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Nov 2025 00:29:07 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vL9aj-002xtk-0v for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Nov 2025 00:29:05 +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 1vL9ai-002xtb-34 for pgsql-hackers@lists.postgresql.org; Tue, 18 Nov 2025 00:29:05 +0000 Received: from mail-qk1-x72d.google.com ([2607:f8b0:4864:20::72d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vL9ag-0005EB-2m for pgsql-hackers@postgresql.org; Tue, 18 Nov 2025 00:29:04 +0000 Received: by mail-qk1-x72d.google.com with SMTP id af79cd13be357-8b25ed53fcbso655659185a.0 for ; Mon, 17 Nov 2025 16:29:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763425740; x=1764030540; darn=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=kTh0d7hSPJKlsxI1dtHB9gzf+Ev27pHmYkfhuATI2Qw=; b=dJoHQw15MEgy9Zd/KhEsGWAX32BPemNvs7hsYAx1qaneRDymUKnrOtikgcsNxtwWzw GVjGxdOGZigVhGLwpGryb7qad7smDpQMZ1ZSRmuqiLd215v9tSPUkx7bq5V4HiTSwlhj n9EiRp3ba5Bus60iStijNOpO+40bLMQOzgm6WriT9jfr30ooQ2CwD2/klpx6PUIX0HwT Nt+9Z/FTNd94qbTR50ThH+6iDf/ZhNEhnjn8O6M6XsgrSgR27/Nty3FZMDNGia1ml4Fw zbtBSftws07MICNm3hTSfLpMVp8la+Vwi0dop7FP2GUhFlz0M0fNGQTDR0vnIiYp7WuP LzYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763425740; x=1764030540; 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=kTh0d7hSPJKlsxI1dtHB9gzf+Ev27pHmYkfhuATI2Qw=; b=KV+61aJq3nFeM3Es3zlzN3oA403P0IGP5HSMmON+Mc5EK07iMnW2MeU5wl3ld3jo4U jYoCIK41wQj/htt75qpPcmCX+Sq23SXDZlRcSKoh2IVJoidsuFJZqLDiyG/zsUoXvC1e rJdEBzJtwj0J6t4Auwqihvo2p7D22LQQXZTZ6tSTpTQmzIeEffmXPaNeHHR8t++dz7tH +dqBk44sehyU8EwjuEy8Y22253PeB+5N8qnytAZAvCoYzq476kQOxumqChQeALANl46c UH8RTsQ+XKvfj0Bg7pPdXwBuK44hXvY6Y9T4X3IbICqZxR059FWfGP5BrRlVPeMcjUb1 9vUw== X-Forwarded-Encrypted: i=1; AJvYcCXqigx4uS3kzSfhUDbbQ16qoI70yur2H6cBRytbWzTlGXORGlUt28D3VZrYtJzL5mQ2aUF4IV2Yl/OBbk29@postgresql.org X-Gm-Message-State: AOJu0YyVQS3eSiqMLg8iLNU9f3HMKiYjuZAXJDYB4JJNuFmcM94Cq4kH jytvTGWwyRDNhNHMUxO3dGWoAyu68GajwpSZjxL4ZYyIHtR3v3oc3MB5 X-Gm-Gg: ASbGncukcJbFquYP2DBCTXa7gI6ciKG3fpep/Sqo93ykfj0wKKyNRRBPE0aJUTcinLE qh69AXxH7f7mrQVZaID0DP/fdGxE9grBBatEwDsA6GIa8Gi6ngdQZCHtMGGkCtCRM7Tyt36U14r loZMJy0QO0fpd6v/H2XNwANtX2Ibuiy+XT0w6mTMcl+rTJpvcYxfJGFQtc7zbD79TSYt0bMwmTF gr3RR0oPdQe7G0JgE0LObB9dNAqG/xzSf9upAnL9sq6pq77yGjGYX/6WvsGuWigk1clyQM5nIqx UaveyFRCCWv/BPIDbOtmyW9WpA9nVxRWVd90aU+a05uQZnVKtaPsV1XqG0AunsDo+bn7r/BGes6 BmBohvTwN4q+ex/e7pvryTnnhP3boftNQ1BcBYHmoF9bj68OxNnNHz23+btHJ4SeZK5pnINbSN5 +3UKPo6TbBMg== X-Google-Smtp-Source: AGHT+IEIqUL4edRbPoXRGyVm4Kq8XMW5fiVrWQXjNevsarF+0bjb15wHB1PJhWN9bvgLSDbuxkckUw== X-Received: by 2002:a05:620a:2985:b0:8b2:f31f:ae20 with SMTP id af79cd13be357-8b2f31fb1a5mr549435485a.24.1763425740299; Mon, 17 Nov 2025 16:29:00 -0800 (PST) Received: from smtpclient.apple ([209.127.78.222]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8b2e519bb84sm530220685a.34.2025.11.17.16.28.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 17 Nov 2025 16:28:59 -0800 (PST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.700.81\)) Subject: Re: [PATCH] Add pg_get_database_ddl() function to reconstruct CREATE DATABASE statement From: Chao Li In-Reply-To: Date: Tue, 18 Nov 2025 08:28:23 +0800 Cc: Japin Li , Quan Zongliang , pgsql-hackers Content-Transfer-Encoding: quoted-printable Message-Id: References: <7daf5cec-4eae-48e0-883e-684476b57531@yeah.net> To: Akshay Joshi , =?utf-8?Q?=C3=81lvaro_Herrera?= X-Mailer: Apple Mail (2.3826.700.81) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Akshay, I just reviewed v3 and got some comments: > On Nov 17, 2025, at 22:34, Akshay Joshi = wrote: >=20 > All the review comments have been addressed in v3 patch. 1 - ruleutils.c ``` + if (dbForm->datconnlimit !=3D 0) + get_formatted_string(&buf, prettyFlags, 1, "CONNECTION = LIMIT =3D %d", + = dbForm->datconnlimit); ``` I think this is wrong. Default value of CONNECTION_LIMIT is -1 rather = than 0. 0 means no connection is allowed, users should intentionally set = the value, thus 0 should be printed. 2 - ruleutils.c ``` + if (!attrIsNull) + get_formatted_string(&buf, prettyFlags, 1, "ICU_RULES =3D = %s", + = quote_identifier(TextDatumGetCString(dbValue))); ``` ICU_RULES should be omitted if provider is not icu. 3 - ruleutils.c ``` + if (!HeapTupleIsValid(tupleDatabase)) + ereport(ERROR, + errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("database with oid %d does not = exist", dbOid)); ``` I believe all existing code use %u to format oid. I ever raised the same = comment to the other get_xxx_ddl patch. 4 - ruleutils.c ``` + /* + * User must have connect privilege for target database. + */ + aclresult =3D object_aclcheck(DatabaseRelationId, dbOid, = GetUserId(), + = ACL_CONNECT); + if (aclresult !=3D ACLCHECK_OK) + { + aclcheck_error(aclresult, OBJECT_DATABASE, + get_database_name(dbOid)); + } ``` I don=E2=80=99t think CONNECT privilege is good enough. By default, a = new user gets CONNECT privilege via the PUBLIC role. I just did a quick = test to confirm that. ``` # Create a new cluster % initdb . % pg_ctl -D . start % createdb evantest % createdb evan # connect to the db % psql -d evantest -U evan psql (19devel) Type "help" for help. # Got into the database successfully=20 # Without any privilege grant, the user can get ddl of the system = database, which seems not good evantest=3D> select pg_get_database_ddl('postgres', true); pg_get_database_ddl ------------------------------------ CREATE DATABASE postgres + WITH + OWNER =3D chaol + ENCODING =3D "UTF8" + LC_COLLATE =3D "en_US.UTF-8"+ LC_CTYPE =3D "en_US.UTF-8" + LOCALE_PROVIDER =3D 'libc' + TABLESPACE =3D pg_default + ALLOW_CONNECTIONS =3D true + CONNECTION LIMIT =3D -1; (1 row) ``` IMO, only super user and database owner should be to get ddl of the = database. 5 - as you can see from the above test output, =E2=80=9C+=E2=80=9D in = the end of every line is weird. 6 - =E2=80=9CWITH=E2=80=9D has the same indent as the parameters, which = doesn=E2=80=99t good look. If we look at the doc = https://www.postgresql.org/docs/18/sql-createdatabase.html, =E2=80=9CWITH=E2= =80=9D takes the first level of indent, and parameters take the second = level of indent. 7 - For those parameters that have default values should be omitted. For = example: ``` evantest=3D> select pg_get_database_ddl('evantest', true); pg_get_database_ddl ------------------------------------ CREATE DATABASE evantest + WITH + OWNER =3D chaol + ENCODING =3D "UTF8" + LC_COLLATE =3D "en_US.UTF-8"+ LC_CTYPE =3D "en_US.UTF-8" + LOCALE_PROVIDER =3D 'libc' + TABLESPACE =3D pg_default + ALLOW_CONNECTIONS =3D true + CONNECTION LIMIT =3D -1; (1 row) ``` I created the database =E2=80=9Cevantest=E2=80=9D without providing any = parameter. I think at least OWNER, TABLESPACE and ALLOW_CNONNECTIONS = should be omitted. For CONNECTION LIMIT, you already have a logic to = omit it but the logic has some problem as comment 1. 8 - ruleutils.c ``` +/* + * get_formatted_string + * + * Return a formatted version of the string. + * + * prettyFlags - Based on prettyFlags the output includes tabs (\t) and + * newlines (\n). + * nTabChars - indent with specified number of tab characters. + * fmt - printf-style format string used by appendStringInfoVA. + */ +static void +get_formatted_string(StringInfo buf, int prettyFlags, int nTabChars, = const char *fmt,...) ``` I don=E2=80=99t feel good with this function, but not because of the = implementation of the function. I have reviewed a bunch of get_xxx_ddl patches submitted by different = persons. All of them are under a big project, however, looks like to me = that all authors work independently without properly coordinated. A = function like this one should be common for all those patches. Maybe = Alvaro can help here, pushing a common function that is used to format = DDL and requesting all patches to use the function. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/