Re: [PATCH] Add pg_get_database_ddl() function to reconstruct CREATE DATABASE statement

From: Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>
To: Akshay Joshi <akshay(dot)joshi(at)enterprisedb(dot)com>
Cc: Kirill Reshke <reshkekirill(at)gmail(dot)com>, Japin Li <japinli(at)hotmail(dot)com>, Rafia Sabih <rafia(dot)pghackers(at)gmail(dot)com>, Álvaro Herrera <alvherre(at)kurilemu(dot)de>, Euler Taveira <euler(at)eulerto(dot)com>, Amul Sul <sulamul(at)gmail(dot)com>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, Quan Zongliang <quanzongliang(at)yeah(dot)net>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [PATCH] Add pg_get_database_ddl() function to reconstruct CREATE DATABASE statement
Date: 2026-03-10 22:05:25
Message-ID: CAN4CZFNU2tFMsQOH5ukOmABQJrBta4wYpuVMAmmek=W+iYitHg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello

Is ruleutils.c the best place for this function?

It's already huge, and it has a different scope: "Functions to convert
stored expressions/querytrees back to source text"

+ /* Fetch the value of COLLATION_VERSION */
+ dbvalue = SysCacheGetAttr(DATABASEOID, tuple_database,
+ Anum_pg_database_datcollversion, &attr_isnull);
+ if (!attr_isnull)
+ get_formatted_string(&buf, pretty_flags, 8, "COLLATION_VERSION = %s",
+ quote_literal_cstr(TextDatumGetCString(dbvalue)));

pg_dumpall only shows this for binary upgrade, otherwise skips it. Is
it okay for this command to print it by default, shouldn't it depend
on is_with_defaults or something similar?

+#ifndef DDL_DEFAULTS_H
+#define DDL_DEFAULTS_H
+
+static const struct
+{
+ struct
+ {
....

This file seems strange. A static const struct in a header with
uppercase names doesn't seem to follow postgres conventions?
DATCONNLIMIT_UNLIMITED alredy exists as a definition, and probably
should be used instead or referenced, or the existing uses should
refer to the new way of defining it.

+ /* Fetch the value of LC_COLLATE */
+ dbvalue = SysCacheGetAttr(DATABASEOID, tuple_database,
+ Anum_pg_database_datcollate, &attr_isnull);
+ if (!attr_isnull)
+ get_formatted_string(&buf, pretty_flags, 8, "LC_COLLATE = %s",
+ quote_literal_cstr(TextDatumGetCString(dbvalue)));
+ /* Fetch the value of LC_CTYPE */
+ dbvalue = SysCacheGetAttr(DATABASEOID, tuple_database,
+ Anum_pg_database_datctype, &attr_isnull);

Can these be ever nulls?

Also, pg_dump only emits LOCALE if ctype==collate, shouldn't this
follow the same pattern?

+ else if (is_with_defaults)
+ get_formatted_string(&buf, pretty_flags, 8, "LOCALE_PROVIDER = libc");

Doesn't pg_dump always emit this? Shouldn't this function follow the
same convention? Emitting it seems to be a safer default, in case
postgres ever changes this.

+ /* Build the CREATE DATABASE statement */
+ appendStringInfo(&buf, "CREATE DATABASE %s",
+ quote_identifier(dbform->datname.data));
+ get_formatted_string(&buf, pretty_flags, 4, "WITH");

Shouldn't we only emit "WITH" if it is actually followed by something,
not unconditionally?

+/*
+ * get_formatted_string
+ *
+ * Return a formatted version of the string.

But it's a void function.

+ else if (!attr_isnull)
+ get_formatted_string(&buf, pretty_flags, 8, "LOCALE = %s",
+ quote_literal_cstr(TextDatumGetCString(dbvalue)));
+

Can this ever happen, shouldn't it be an assertion instead?

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2026-03-10 22:08:35 Re: Problems with get_actual_variable_range's VISITED_PAGES_LIMIT
Previous Message Jacob Champion 2026-03-10 21:52:38 Re: Improve OAuth discovery logging