From b524b4c931412bb241314f6d0c412c5bd800a246 Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Tue, 28 Oct 2025 14:22:22 +0100 Subject: [PATCH 1/7] WIP pretty printing support --- doc/src/sgml/func/func-info.sgml | 5 ++- src/backend/utils/adt/ruleutils.c | 61 +++++++++++++++++++++++++------ src/include/catalog/pg_proc.dat | 3 ++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 9a937df960d96..338db8a182415 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3827,8 +3827,9 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_domain_ddl - pg_get_domain_ddl ( domain text ) - regtype + pg_get_domain_ddl ( domain regtype + pretty boolean ) + text Reconstructs the creating command for a domain. diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index ca2d162370b57..e604b103776de 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -546,6 +546,7 @@ static void get_json_table_nested_columns(TableFunc *tf, JsonTablePlan *plan, deparse_context *context, bool showimplicit, bool needcomma); +static char *pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags); #define only_marker(rte) ((rte)->inh ? "" : "ONLY ") @@ -13787,7 +13788,7 @@ scan_domain_constraints(Oid domain_oid, List **validcons, List **invalidcons) */ static void build_create_domain_statement(StringInfo buf, Form_pg_type typForm, - Node *defaultExpr, List *validConstraints) + Node *defaultExpr, List *validConstraints, int prettyFlags) { HeapTuple baseTypeTuple; Form_pg_type baseTypeForm; @@ -13822,7 +13823,8 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, /* Add default value if present */ if (defaultExpr != NULL) { - char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, 0, 0); + char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, prettyFlags, 0); + appendStringInfo(buf, " DEFAULT %s", defaultValue); } @@ -13837,7 +13839,7 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, /* Look up the constraint info */ constraintTup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid)); if (!HeapTupleIsValid(constraintTup)) - continue; /* constraint was dropped concurrently */ + continue; /* constraint was dropped concurrently */ con = (Form_pg_constraint) GETSTRUCT(constraintTup); constraintDef = pg_get_constraintdef_worker(constraintOid, false, PRETTYFLAG_PAREN, true); @@ -13856,14 +13858,14 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, * Helper function to add ALTER DOMAIN statements for invalid constraints */ static void -add_alter_domain_statements(StringInfo buf, List *invalidConstraints) +add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int prettyFlags) { - ListCell *lc; + ListCell *lc; foreach(lc, invalidConstraints) { - Oid constraintOid = lfirst_oid(lc); - char *alterStmt = pg_get_constraintdef_worker(constraintOid, true, PRETTYFLAG_PAREN, true); + Oid constraintOid = lfirst_oid(lc); + char *alterStmt = pg_get_constraintdef_worker(constraintOid, true, prettyFlags, true); if (alterStmt) appendStringInfo(buf, "\n%s;", alterStmt); @@ -13876,8 +13878,40 @@ add_alter_domain_statements(StringInfo buf, List *invalidConstraints) Datum pg_get_domain_ddl(PG_FUNCTION_ARGS) { - StringInfoData buf; Oid domain_oid = PG_GETARG_OID(0); + char *res; + + res = pg_get_domain_ddl_worker(domain_oid, 0); + if (res == NULL) + PG_RETURN_NULL(); + PG_RETURN_TEXT_P(string_to_text(res)); +} + +/* + * pg_get_domain_ddl_ext - Get CREATE DOMAIN statement for a domain with pretty-print option + */ +Datum +pg_get_domain_ddl_ext(PG_FUNCTION_ARGS) +{ + Oid domain_oid = PG_GETARG_OID(0); + bool pretty = PG_GETARG_BOOL(1); + char *res; + int prettyFlags; + + prettyFlags = GET_PRETTY_FLAGS(pretty); + + res = pg_get_domain_ddl_worker(domain_oid, prettyFlags); + if (res == NULL) + PG_RETURN_NULL(); + PG_RETURN_TEXT_P(string_to_text(res)); +} + + + +static char * +pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags) +{ + StringInfoData buf; HeapTuple typeTuple; Form_pg_type typForm; Node *defaultExpr; @@ -13887,10 +13921,13 @@ pg_get_domain_ddl(PG_FUNCTION_ARGS) /* Look up the domain in pg_type */ typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(domain_oid)); if (!HeapTupleIsValid(typeTuple)) - PG_RETURN_NULL(); + return NULL; typForm = (Form_pg_type) GETSTRUCT(typeTuple); + elog(WARNING, "pretty flags are %i", prettyFlags); + + /* Get default expression */ defaultExpr = get_typdefault(domain_oid); @@ -13899,16 +13936,16 @@ pg_get_domain_ddl(PG_FUNCTION_ARGS) /* Build the DDL statement */ initStringInfo(&buf); - build_create_domain_statement(&buf, typForm, defaultExpr, validConstraints); + build_create_domain_statement(&buf, typForm, defaultExpr, validConstraints, prettyFlags); /* Add ALTER DOMAIN statements for invalid constraints */ if (list_length(invalidConstraints) > 0) - add_alter_domain_statements(&buf, invalidConstraints); + add_alter_domain_statements(&buf, invalidConstraints, prettyFlags); /* Cleanup */ list_free(validConstraints); list_free(invalidConstraints); ReleaseSysCache(typeTuple); - PG_RETURN_TEXT_P(cstring_to_text(buf.data)); + return buf.data; } diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index e0b40f96004a3..8da4d5b60db40 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8518,6 +8518,9 @@ { oid => '8024', descr => 'get CREATE statement for DOMAIN', proname => 'pg_get_domain_ddl', prorettype => 'text', proargtypes => 'regtype', prosrc => 'pg_get_domain_ddl' }, +{ oid => '8025', descr => 'get CREATE statement for DOMAIN with pretty option', + proname => 'pg_get_domain_ddl', prorettype => 'text', + proargtypes => 'regtype bool', prosrc => 'pg_get_domain_ddl_ext' }, { oid => '2509', descr => 'deparse an encoded expression with pretty-print option', proname => 'pg_get_expr', provolatile => 's', prorettype => 'text', From 91b8595a9b52049db239c813c3ef9403431e756e Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Fri, 31 Oct 2025 14:24:13 +0100 Subject: [PATCH 2/7] adopt get_formatted_string from https://github.com/akshay-joshi --- src/backend/utils/adt/ruleutils.c | 79 +++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e604b103776de..d711723e6c9df 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -546,6 +546,10 @@ static void get_json_table_nested_columns(TableFunc *tf, JsonTablePlan *plan, deparse_context *context, bool showimplicit, bool needcomma); +static void get_formatted_string(StringInfo buf, + int prettyFlags, + int noOfTabChars, + const char *fmt,...) pg_attribute_printf(4, 5); static char *pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags); #define only_marker(rte) ((rte)->inh ? "" : "ONLY ") @@ -13740,6 +13744,40 @@ get_range_partbound_string(List *bound_datums) return buf->data; } +/* + * get_formatted_string + * + * Return a formatted version of the string. + * + * pretty - If pretty is true, the output includes tabs (\t) and newlines (\n). + * noOfTabChars - indent with specified no of tabs. + * fmt - printf-style format string used by appendStringInfoVA. + */ +static void +get_formatted_string(StringInfo buf, int prettyFlags, int noOfTabChars, const char *fmt,...) +{ + va_list args; + + if (prettyFlags & PRETTYFLAG_INDENT) + { + /* Indent with tabs */ + for (int i = 0; i < noOfTabChars; i++) + { + appendStringInfoChar(buf, '\t'); + } + } + else + appendStringInfoChar(buf, ' '); + + va_start(args, fmt); + appendStringInfoVA(buf, fmt, args); + va_end(args); + + /* If pretty mode, append newline at the end */ + if (prettyFlags & PRETTYFLAG_INDENT) + appendStringInfoChar(buf, '\n'); +} + /* * Helper function to scan domain constraints @@ -13787,7 +13825,7 @@ scan_domain_constraints(Oid domain_oid, List **validcons, List **invalidcons) * Helper function to build CREATE DOMAIN statement */ static void -build_create_domain_statement(StringInfo buf, Form_pg_type typForm, +build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, Node *defaultExpr, List *validConstraints, int prettyFlags) { HeapTuple baseTypeTuple; @@ -13795,10 +13833,10 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, Oid baseCollation = InvalidOid; ListCell *lc; - appendStringInfo(buf, "CREATE DOMAIN %s.%s AS %s", - quote_identifier(get_namespace_name(typForm->typnamespace)), - quote_identifier(NameStr(typForm->typname)), - format_type_be(typForm->typbasetype)); + get_formatted_string(&buf, prettyFlags, 0, "CREATE DOMAIN %s.%s AS %s", + quote_identifier(get_namespace_name(typForm->typnamespace)), + quote_identifier(NameStr(typForm->typname)), + format_type_be(typForm->typbasetype)); /* Add collation if it differs from base type's collation */ if (OidIsValid(typForm->typcollation)) @@ -13815,8 +13853,8 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, /* Only add COLLATE if domain's collation differs from base type's */ if (typForm->typcollation != baseCollation) { - appendStringInfo(buf, " COLLATE %s", - generate_collation_name(typForm->typcollation)); + get_formatted_string(&buf, prettyFlags, 1, "COLLATE %s", + generate_collation_name(typForm->typcollation)); } } @@ -13825,7 +13863,7 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, { char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, prettyFlags, 0); - appendStringInfo(buf, " DEFAULT %s", defaultValue); + get_formatted_string(&buf, prettyFlags, 1, "DEFAULT %s", defaultValue); } /* Add valid constraints */ @@ -13842,23 +13880,27 @@ build_create_domain_statement(StringInfo buf, Form_pg_type typForm, continue; /* constraint was dropped concurrently */ con = (Form_pg_constraint) GETSTRUCT(constraintTup); - constraintDef = pg_get_constraintdef_worker(constraintOid, false, PRETTYFLAG_PAREN, true); + constraintDef = pg_get_constraintdef_worker(constraintOid, false, prettyFlags, true); - appendStringInfo(buf, " CONSTRAINT %s %s", - quote_identifier(NameStr(con->conname)), - constraintDef); + get_formatted_string(&buf, prettyFlags, 1, "CONSTRAINT %s", + quote_identifier(NameStr(con->conname))); + get_formatted_string(&buf, prettyFlags, 2, "%s", constraintDef); ReleaseSysCache(constraintTup); } - appendStringInfoChar(buf, ';'); + /* Replace '\n' with ';' if newline at the end */ + if (buf.len > 0 && buf.data[buf.len - 1] == '\n') + buf.data[buf.len - 1] = ';'; + else + appendStringInfoChar(&buf, ';'); } /* * Helper function to add ALTER DOMAIN statements for invalid constraints */ static void -add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int prettyFlags) +add_alter_domain_statements(StringInfoData buf, List *invalidConstraints, int prettyFlags) { ListCell *lc; @@ -13868,7 +13910,7 @@ add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int pretty char *alterStmt = pg_get_constraintdef_worker(constraintOid, true, prettyFlags, true); if (alterStmt) - appendStringInfo(buf, "\n%s;", alterStmt); + get_formatted_string(&buf, prettyFlags, 0, "\n%s;", alterStmt); } } @@ -13925,9 +13967,6 @@ pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags) typForm = (Form_pg_type) GETSTRUCT(typeTuple); - elog(WARNING, "pretty flags are %i", prettyFlags); - - /* Get default expression */ defaultExpr = get_typdefault(domain_oid); @@ -13936,11 +13975,11 @@ pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags) /* Build the DDL statement */ initStringInfo(&buf); - build_create_domain_statement(&buf, typForm, defaultExpr, validConstraints, prettyFlags); + build_create_domain_statement(buf, typForm, defaultExpr, validConstraints, prettyFlags); /* Add ALTER DOMAIN statements for invalid constraints */ if (list_length(invalidConstraints) > 0) - add_alter_domain_statements(&buf, invalidConstraints, prettyFlags); + add_alter_domain_statements(buf, invalidConstraints, prettyFlags); /* Cleanup */ list_free(validConstraints); From af01afaaaedb6ab16369a404ae5f2697e6d68275 Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Fri, 31 Oct 2025 14:54:53 +0100 Subject: [PATCH 3/7] avoid newline replace --- src/backend/utils/adt/ruleutils.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d711723e6c9df..96ebf83dfadb7 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -13760,6 +13760,7 @@ get_formatted_string(StringInfo buf, int prettyFlags, int noOfTabChars, const ch if (prettyFlags & PRETTYFLAG_INDENT) { + appendStringInfoChar(buf, '\n'); /* Indent with tabs */ for (int i = 0; i < noOfTabChars; i++) { @@ -13772,10 +13773,6 @@ get_formatted_string(StringInfo buf, int prettyFlags, int noOfTabChars, const ch va_start(args, fmt); appendStringInfoVA(buf, fmt, args); va_end(args); - - /* If pretty mode, append newline at the end */ - if (prettyFlags & PRETTYFLAG_INDENT) - appendStringInfoChar(buf, '\n'); } @@ -13833,10 +13830,10 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, Oid baseCollation = InvalidOid; ListCell *lc; - get_formatted_string(&buf, prettyFlags, 0, "CREATE DOMAIN %s.%s AS %s", - quote_identifier(get_namespace_name(typForm->typnamespace)), - quote_identifier(NameStr(typForm->typname)), - format_type_be(typForm->typbasetype)); + appendStringInfo(&buf, "CREATE DOMAIN %s.%s AS %s", + quote_identifier(get_namespace_name(typForm->typnamespace)), + quote_identifier(NameStr(typForm->typname)), + format_type_be(typForm->typbasetype)); /* Add collation if it differs from base type's collation */ if (OidIsValid(typForm->typcollation)) @@ -13889,11 +13886,7 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, ReleaseSysCache(constraintTup); } - /* Replace '\n' with ';' if newline at the end */ - if (buf.len > 0 && buf.data[buf.len - 1] == '\n') - buf.data[buf.len - 1] = ';'; - else - appendStringInfoChar(&buf, ';'); + appendStringInfoChar(&buf, ';'); } /* From d62732a53328e8993a3782ce2c0f1c93b769c258 Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Fri, 31 Oct 2025 15:03:09 +0100 Subject: [PATCH 4/7] fix alter-domain handling --- src/backend/utils/adt/ruleutils.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 96ebf83dfadb7..1b7f02223d45f 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -13822,7 +13822,7 @@ scan_domain_constraints(Oid domain_oid, List **validcons, List **invalidcons) * Helper function to build CREATE DOMAIN statement */ static void -build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, +build_create_domain_statement(StringInfo buf, Form_pg_type typForm, Node *defaultExpr, List *validConstraints, int prettyFlags) { HeapTuple baseTypeTuple; @@ -13830,7 +13830,7 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, Oid baseCollation = InvalidOid; ListCell *lc; - appendStringInfo(&buf, "CREATE DOMAIN %s.%s AS %s", + appendStringInfo(buf, "CREATE DOMAIN %s.%s AS %s", quote_identifier(get_namespace_name(typForm->typnamespace)), quote_identifier(NameStr(typForm->typname)), format_type_be(typForm->typbasetype)); @@ -13850,7 +13850,7 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, /* Only add COLLATE if domain's collation differs from base type's */ if (typForm->typcollation != baseCollation) { - get_formatted_string(&buf, prettyFlags, 1, "COLLATE %s", + get_formatted_string(buf, prettyFlags, 1, "COLLATE %s", generate_collation_name(typForm->typcollation)); } } @@ -13860,7 +13860,7 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, { char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, prettyFlags, 0); - get_formatted_string(&buf, prettyFlags, 1, "DEFAULT %s", defaultValue); + get_formatted_string(buf, prettyFlags, 1, "DEFAULT %s", defaultValue); } /* Add valid constraints */ @@ -13879,21 +13879,21 @@ build_create_domain_statement(StringInfoData buf, Form_pg_type typForm, con = (Form_pg_constraint) GETSTRUCT(constraintTup); constraintDef = pg_get_constraintdef_worker(constraintOid, false, prettyFlags, true); - get_formatted_string(&buf, prettyFlags, 1, "CONSTRAINT %s", + get_formatted_string(buf, prettyFlags, 1, "CONSTRAINT %s", quote_identifier(NameStr(con->conname))); - get_formatted_string(&buf, prettyFlags, 2, "%s", constraintDef); + get_formatted_string(buf, prettyFlags, 2, "%s", constraintDef); ReleaseSysCache(constraintTup); } - appendStringInfoChar(&buf, ';'); + appendStringInfoChar(buf, ';'); } /* * Helper function to add ALTER DOMAIN statements for invalid constraints */ static void -add_alter_domain_statements(StringInfoData buf, List *invalidConstraints, int prettyFlags) +add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int prettyFlags) { ListCell *lc; @@ -13903,7 +13903,7 @@ add_alter_domain_statements(StringInfoData buf, List *invalidConstraints, int pr char *alterStmt = pg_get_constraintdef_worker(constraintOid, true, prettyFlags, true); if (alterStmt) - get_formatted_string(&buf, prettyFlags, 0, "\n%s;", alterStmt); + get_formatted_string(buf, prettyFlags, 0, "%s;", alterStmt); } } @@ -13968,11 +13968,11 @@ pg_get_domain_ddl_worker(Oid domain_oid, int prettyFlags) /* Build the DDL statement */ initStringInfo(&buf); - build_create_domain_statement(buf, typForm, defaultExpr, validConstraints, prettyFlags); + build_create_domain_statement(&buf, typForm, defaultExpr, validConstraints, prettyFlags); /* Add ALTER DOMAIN statements for invalid constraints */ if (list_length(invalidConstraints) > 0) - add_alter_domain_statements(buf, invalidConstraints, prettyFlags); + add_alter_domain_statements(&buf, invalidConstraints, prettyFlags); /* Cleanup */ list_free(validConstraints); From ed954ddc63d95f4f534bb4573d5019987f9ed6ea Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Mon, 3 Nov 2025 15:22:23 +0100 Subject: [PATCH 5/7] use default for function --- src/backend/catalog/system_functions.sql | 6 ++++++ src/backend/utils/adt/ruleutils.c | 22 ++++++---------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 2d946d6d9e9bc..5a96ff1efcbe7 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -657,6 +657,12 @@ LANGUAGE INTERNAL STRICT VOLATILE PARALLEL UNSAFE AS 'pg_replication_origin_session_setup'; +CREATE OR REPLACE FUNCTION + pg_get_domain_ddl(domain_name regtype, pretty bool DEFAULT false) + RETURNS text + LANGUAGE internal +AS 'pg_get_domain_ddl_ext'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 1b7f02223d45f..c1c7fdc40fe36 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -94,6 +94,10 @@ ((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \ : PRETTYFLAG_INDENT) +#define GET_DDL_PRETTY_FLAGS(pretty) \ + ((pretty) ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) \ + : 0) + /* Default line length for pretty-print wrapping: 0 means wrap always */ #define WRAP_COLUMN_DEFAULT 0 @@ -13907,21 +13911,6 @@ add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int pretty } } -/* - * pg_get_domain_ddl - Get CREATE DOMAIN statement for a domain - */ -Datum -pg_get_domain_ddl(PG_FUNCTION_ARGS) -{ - Oid domain_oid = PG_GETARG_OID(0); - char *res; - - res = pg_get_domain_ddl_worker(domain_oid, 0); - if (res == NULL) - PG_RETURN_NULL(); - PG_RETURN_TEXT_P(string_to_text(res)); -} - /* * pg_get_domain_ddl_ext - Get CREATE DOMAIN statement for a domain with pretty-print option */ @@ -13933,7 +13922,8 @@ pg_get_domain_ddl_ext(PG_FUNCTION_ARGS) char *res; int prettyFlags; - prettyFlags = GET_PRETTY_FLAGS(pretty); + prettyFlags = GET_DDL_PRETTY_FLAGS(pretty); + elog(WARNING, "pretty flags are %i", prettyFlags); res = pg_get_domain_ddl_worker(domain_oid, prettyFlags); if (res == NULL) diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 8da4d5b60db40..49cfb6c1df22f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8515,10 +8515,7 @@ { oid => '2508', descr => 'constraint description with pretty-print option', proname => 'pg_get_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid bool', prosrc => 'pg_get_constraintdef_ext' }, -{ oid => '8024', descr => 'get CREATE statement for DOMAIN', - proname => 'pg_get_domain_ddl', prorettype => 'text', - proargtypes => 'regtype', prosrc => 'pg_get_domain_ddl' }, -{ oid => '8025', descr => 'get CREATE statement for DOMAIN with pretty option', +{ oid => '8024', descr => 'get CREATE statement for DOMAIN with pretty option', proname => 'pg_get_domain_ddl', prorettype => 'text', proargtypes => 'regtype bool', prosrc => 'pg_get_domain_ddl_ext' }, { oid => '2509', From ec1d4892671fb6c212b24e35d7267d751ee9bca9 Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Mon, 3 Nov 2025 17:06:10 +0100 Subject: [PATCH 6/7] adjust existing regression tests --- src/backend/utils/adt/ruleutils.c | 3 +- src/test/regress/expected/object_ddl.out | 58 ++++++++++++------------ 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index c1c7fdc40fe36..54e2608382814 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -13907,7 +13907,7 @@ add_alter_domain_statements(StringInfo buf, List *invalidConstraints, int pretty char *alterStmt = pg_get_constraintdef_worker(constraintOid, true, prettyFlags, true); if (alterStmt) - get_formatted_string(buf, prettyFlags, 0, "%s;", alterStmt); + appendStringInfo(buf, "\n%s;", alterStmt); } } @@ -13923,7 +13923,6 @@ pg_get_domain_ddl_ext(PG_FUNCTION_ARGS) int prettyFlags; prettyFlags = GET_DDL_PRETTY_FLAGS(pretty); - elog(WARNING, "pretty flags are %i", prettyFlags); res = pg_get_domain_ddl_worker(domain_oid, prettyFlags); if (res == NULL) diff --git a/src/test/regress/expected/object_ddl.out b/src/test/regress/expected/object_ddl.out index 3dc1f1bc04963..cf673986cb8fe 100644 --- a/src/test/regress/expected/object_ddl.out +++ b/src/test/regress/expected/object_ddl.out @@ -10,9 +10,9 @@ CREATE DOMAIN regress_us_postal_code AS TEXT OR VALUE ~ '^\d{5}-\d{4}$' ); SELECT pg_get_domain_ddl('regress_us_postal_code'); - pg_get_domain_ddl -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_us_postal_code AS text DEFAULT '00000'::text CONSTRAINT regress_us_postal_code_check CHECK (VALUE ~ '^\d{5}$'::text OR VALUE ~ '^\d{5}-\d{4}$'::text); + pg_get_domain_ddl +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_us_postal_code AS text DEFAULT '00000'::text CONSTRAINT regress_us_postal_code_check CHECK (((VALUE ~ '^\d{5}$'::text) OR (VALUE ~ '^\d{5}-\d{4}$'::text))); (1 row) CREATE DOMAIN regress_domain_not_null AS INT NOT NULL; @@ -26,9 +26,9 @@ CREATE DOMAIN regress_domain_check AS INT CONSTRAINT regress_a CHECK (VALUE < 100) CONSTRAINT regress_b CHECK (VALUE > 10); SELECT pg_get_domain_ddl('regress_domain_check'); - pg_get_domain_ddl ----------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_domain_check AS integer CONSTRAINT regress_a CHECK (VALUE < 100) CONSTRAINT regress_b CHECK (VALUE > 10); + pg_get_domain_ddl +-------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_domain_check AS integer CONSTRAINT regress_a CHECK ((VALUE < 100)) CONSTRAINT regress_b CHECK ((VALUE > 10)); (1 row) CREATE DOMAIN "regress_domain with space" AS INT @@ -36,9 +36,9 @@ CREATE DOMAIN "regress_domain with space" AS INT CONSTRAINT "regress_Constraint B" CHECK (VALUE > 10) CONSTRAINT "regress_ConstraintC" CHECK (VALUE != 55); SELECT pg_get_domain_ddl('"regress_domain with space"'); - pg_get_domain_ddl ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - CREATE DOMAIN public."regress_domain with space" AS integer CONSTRAINT regress_a CHECK (VALUE < 100) CONSTRAINT "regress_Constraint B" CHECK (VALUE > 10) CONSTRAINT "regress_ConstraintC" CHECK (VALUE <> 55); + pg_get_domain_ddl +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public."regress_domain with space" AS integer CONSTRAINT regress_a CHECK ((VALUE < 100)) CONSTRAINT "regress_Constraint B" CHECK ((VALUE > 10)) CONSTRAINT "regress_ConstraintC" CHECK ((VALUE <> 55)); (1 row) -- Test error cases @@ -64,9 +64,9 @@ SELECT pg_get_domain_ddl('regress_simple_domain'); CREATE DOMAIN regress_base_domain AS varchar(10); CREATE DOMAIN regress_derived_domain AS regress_base_domain CHECK (LENGTH(VALUE) > 3); SELECT pg_get_domain_ddl('regress_derived_domain'); - pg_get_domain_ddl ---------------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_derived_domain AS regress_base_domain CONSTRAINT regress_derived_domain_check CHECK (length(VALUE::text) > 3); + pg_get_domain_ddl +------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_derived_domain AS regress_base_domain CONSTRAINT regress_derived_domain_check CHECK ((length((VALUE)::text) > 3)); (1 row) -- Test domain with complex default expressions @@ -97,9 +97,9 @@ SELECT pg_get_domain_ddl('regress_precise_numeric'); -- Test domain over array type CREATE DOMAIN regress_int_array_domain AS int[] CHECK (array_length(VALUE, 1) <= 5); SELECT pg_get_domain_ddl('regress_int_array_domain'); - pg_get_domain_ddl -------------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_int_array_domain AS integer[] CONSTRAINT regress_int_array_domain_check CHECK (array_length(VALUE, 1) <= 5); + pg_get_domain_ddl +--------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_int_array_domain AS integer[] CONSTRAINT regress_int_array_domain_check CHECK ((array_length(VALUE, 1) <= 5)); (1 row) -- Test domain in non-public schema @@ -118,38 +118,38 @@ CREATE DOMAIN regress_comprehensive_domain AS varchar(50) CHECK (LENGTH(VALUE) >= 5) CHECK (VALUE !~ '^\s*$'); -- not just whitespace SELECT pg_get_domain_ddl('regress_comprehensive_domain'); - pg_get_domain_ddl -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_comprehensive_domain AS character varying DEFAULT 'default_value'::character varying CONSTRAINT regress_comprehensive_domain_not_null NOT NULL CONSTRAINT regress_comprehensive_domain_check CHECK (length(VALUE::text) >= 5) CONSTRAINT regress_comprehensive_domain_check1 CHECK (VALUE::text !~ '^\s*$'::text); + pg_get_domain_ddl +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_comprehensive_domain AS character varying DEFAULT 'default_value'::character varying CONSTRAINT regress_comprehensive_domain_not_null NOT NULL CONSTRAINT regress_comprehensive_domain_check CHECK ((length((VALUE)::text) >= 5)) CONSTRAINT regress_comprehensive_domain_check1 CHECK (((VALUE)::text !~ '^\s*$'::text)); (1 row) -- Test domain over composite type CREATE TYPE regress_address_type AS (street text, city text, zipcode text); CREATE DOMAIN regress_address_domain AS regress_address_type CHECK ((VALUE).zipcode ~ '^\d{5}$'); SELECT pg_get_domain_ddl('regress_address_domain'); - pg_get_domain_ddl --------------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_address_domain AS regress_address_type CONSTRAINT regress_address_domain_check CHECK ((VALUE).zipcode ~ '^\d{5}$'::text); + pg_get_domain_ddl +---------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_address_domain AS regress_address_type CONSTRAINT regress_address_domain_check CHECK (((VALUE).zipcode ~ '^\d{5}$'::text)); (1 row) -- Test domain with NOT VALID constraint CREATE DOMAIN regress_domain_not_valid AS int; ALTER DOMAIN regress_domain_not_valid ADD CONSTRAINT check_positive CHECK (VALUE > 0) NOT VALID; SELECT pg_get_domain_ddl('regress_domain_not_valid'); - pg_get_domain_ddl ---------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_domain_not_valid AS integer; + - ALTER DOMAIN public.regress_domain_not_valid ADD CONSTRAINT check_positive CHECK (VALUE > 0) NOT VALID; + pg_get_domain_ddl +----------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_domain_not_valid AS integer; + + ALTER DOMAIN public.regress_domain_not_valid ADD CONSTRAINT check_positive CHECK ((VALUE > 0)) NOT VALID; (1 row) -- Test domain with mix of valid and not valid constraints CREATE DOMAIN regress_domain_mixed AS int CHECK (VALUE != 0); ALTER DOMAIN regress_domain_mixed ADD CONSTRAINT check_range CHECK (VALUE BETWEEN 1 AND 100) NOT VALID; SELECT pg_get_domain_ddl('regress_domain_mixed'); - pg_get_domain_ddl --------------------------------------------------------------------------------------------------------------------- - CREATE DOMAIN public.regress_domain_mixed AS integer CONSTRAINT regress_domain_mixed_check CHECK (VALUE <> 0); + - ALTER DOMAIN public.regress_domain_mixed ADD CONSTRAINT check_range CHECK (VALUE >= 1 AND VALUE <= 100) NOT VALID; + pg_get_domain_ddl +-------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_domain_mixed AS integer CONSTRAINT regress_domain_mixed_check CHECK ((VALUE <> 0)); + + ALTER DOMAIN public.regress_domain_mixed ADD CONSTRAINT check_range CHECK (((VALUE >= 1) AND (VALUE <= 100))) NOT VALID; (1 row) -- Test domain with collation From 626f876df6837972a1010b6cc7198a1bbf19b099 Mon Sep 17 00:00:00 2001 From: Tim Waizenegger Date: Mon, 3 Nov 2025 17:19:56 +0100 Subject: [PATCH 7/7] add regression tests for pretty output --- src/test/regress/expected/object_ddl.out | 146 +++++++++++++++++++++++ src/test/regress/sql/object_ddl.sql | 18 +++ 2 files changed, 164 insertions(+) diff --git a/src/test/regress/expected/object_ddl.out b/src/test/regress/expected/object_ddl.out index cf673986cb8fe..a72109ab9fbac 100644 --- a/src/test/regress/expected/object_ddl.out +++ b/src/test/regress/expected/object_ddl.out @@ -15,6 +15,36 @@ SELECT pg_get_domain_ddl('regress_us_postal_code'); CREATE DOMAIN public.regress_us_postal_code AS text DEFAULT '00000'::text CONSTRAINT regress_us_postal_code_check CHECK (((VALUE ~ '^\d{5}$'::text) OR (VALUE ~ '^\d{5}-\d{4}$'::text))); (1 row) +SELECT pg_get_domain_ddl('regress_us_postal_code', pretty => false); + pg_get_domain_ddl +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_us_postal_code AS text DEFAULT '00000'::text CONSTRAINT regress_us_postal_code_check CHECK (((VALUE ~ '^\d{5}$'::text) OR (VALUE ~ '^\d{5}-\d{4}$'::text))); +(1 row) + +SELECT pg_get_domain_ddl('regress_us_postal_code', false); + pg_get_domain_ddl +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_us_postal_code AS text DEFAULT '00000'::text CONSTRAINT regress_us_postal_code_check CHECK (((VALUE ~ '^\d{5}$'::text) OR (VALUE ~ '^\d{5}-\d{4}$'::text))); +(1 row) + +SELECT pg_get_domain_ddl('regress_us_postal_code', pretty => true); + pg_get_domain_ddl +----------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_us_postal_code AS text + + DEFAULT '00000'::text + + CONSTRAINT regress_us_postal_code_check + + CHECK (VALUE ~ '^\d{5}$'::text OR VALUE ~ '^\d{5}-\d{4}$'::text); +(1 row) + +SELECT pg_get_domain_ddl('regress_us_postal_code', true); + pg_get_domain_ddl +----------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_us_postal_code AS text + + DEFAULT '00000'::text + + CONSTRAINT regress_us_postal_code_check + + CHECK (VALUE ~ '^\d{5}$'::text OR VALUE ~ '^\d{5}-\d{4}$'::text); +(1 row) + CREATE DOMAIN regress_domain_not_null AS INT NOT NULL; SELECT pg_get_domain_ddl('regress_domain_not_null'); pg_get_domain_ddl @@ -22,6 +52,14 @@ SELECT pg_get_domain_ddl('regress_domain_not_null'); CREATE DOMAIN public.regress_domain_not_null AS integer CONSTRAINT regress_domain_not_null_not_null NOT NULL; (1 row) +SELECT pg_get_domain_ddl('regress_domain_not_null', pretty => true); + pg_get_domain_ddl +--------------------------------------------------------- + CREATE DOMAIN public.regress_domain_not_null AS integer+ + CONSTRAINT regress_domain_not_null_not_null + + NOT NULL; +(1 row) + CREATE DOMAIN regress_domain_check AS INT CONSTRAINT regress_a CHECK (VALUE < 100) CONSTRAINT regress_b CHECK (VALUE > 10); @@ -31,6 +69,16 @@ SELECT pg_get_domain_ddl('regress_domain_check'); CREATE DOMAIN public.regress_domain_check AS integer CONSTRAINT regress_a CHECK ((VALUE < 100)) CONSTRAINT regress_b CHECK ((VALUE > 10)); (1 row) +SELECT pg_get_domain_ddl('regress_domain_check', pretty => true); + pg_get_domain_ddl +------------------------------------------------------ + CREATE DOMAIN public.regress_domain_check AS integer+ + CONSTRAINT regress_a + + CHECK (VALUE < 100) + + CONSTRAINT regress_b + + CHECK (VALUE > 10); +(1 row) + CREATE DOMAIN "regress_domain with space" AS INT CONSTRAINT regress_a CHECK (VALUE < 100) CONSTRAINT "regress_Constraint B" CHECK (VALUE > 10) @@ -41,6 +89,18 @@ SELECT pg_get_domain_ddl('"regress_domain with space"'); CREATE DOMAIN public."regress_domain with space" AS integer CONSTRAINT regress_a CHECK ((VALUE < 100)) CONSTRAINT "regress_Constraint B" CHECK ((VALUE > 10)) CONSTRAINT "regress_ConstraintC" CHECK ((VALUE <> 55)); (1 row) +SELECT pg_get_domain_ddl('"regress_domain with space"', pretty => true); + pg_get_domain_ddl +------------------------------------------------------------- + CREATE DOMAIN public."regress_domain with space" AS integer+ + CONSTRAINT regress_a + + CHECK (VALUE < 100) + + CONSTRAINT "regress_Constraint B" + + CHECK (VALUE > 10) + + CONSTRAINT "regress_ConstraintC" + + CHECK (VALUE <> 55); +(1 row) + -- Test error cases SELECT pg_get_domain_ddl('regress_nonexistent_domain'::regtype); -- should fail ERROR: type "regress_nonexistent_domain" does not exist @@ -52,6 +112,12 @@ SELECT pg_get_domain_ddl(NULL); -- should return NULL (1 row) +SELECT pg_get_domain_ddl(NULL, pretty => true); -- should return NULL + pg_get_domain_ddl +------------------- + +(1 row) + -- Test domains with no constraints CREATE DOMAIN regress_simple_domain AS text; SELECT pg_get_domain_ddl('regress_simple_domain'); @@ -60,6 +126,12 @@ SELECT pg_get_domain_ddl('regress_simple_domain'); CREATE DOMAIN public.regress_simple_domain AS text; (1 row) +SELECT pg_get_domain_ddl('regress_simple_domain', pretty => true); + pg_get_domain_ddl +----------------------------------------------------- + CREATE DOMAIN public.regress_simple_domain AS text; +(1 row) + -- Test domain over another domain CREATE DOMAIN regress_base_domain AS varchar(10); CREATE DOMAIN regress_derived_domain AS regress_base_domain CHECK (LENGTH(VALUE) > 3); @@ -69,6 +141,14 @@ SELECT pg_get_domain_ddl('regress_derived_domain'); CREATE DOMAIN public.regress_derived_domain AS regress_base_domain CONSTRAINT regress_derived_domain_check CHECK ((length((VALUE)::text) > 3)); (1 row) +SELECT pg_get_domain_ddl('regress_derived_domain', pretty => true); + pg_get_domain_ddl +-------------------------------------------------------------------- + CREATE DOMAIN public.regress_derived_domain AS regress_base_domain+ + CONSTRAINT regress_derived_domain_check + + CHECK (length(VALUE::text) > 3); +(1 row) + -- Test domain with complex default expressions CREATE SEQUENCE regress_test_seq; CREATE DOMAIN regress_seq_domain AS int DEFAULT nextval('regress_test_seq'); @@ -78,6 +158,13 @@ SELECT pg_get_domain_ddl('regress_seq_domain'); CREATE DOMAIN public.regress_seq_domain AS integer DEFAULT nextval('regress_test_seq'::regclass); (1 row) +SELECT pg_get_domain_ddl('regress_seq_domain', pretty => true); + pg_get_domain_ddl +-------------------------------------------------------- + CREATE DOMAIN public.regress_seq_domain AS integer + + DEFAULT nextval('regress_test_seq'::regclass); +(1 row) + -- Test domain with a renamed sequence as default expression ALTER SEQUENCE regress_test_seq RENAME TO regress_test_seq_renamed; SELECT pg_get_domain_ddl('regress_seq_domain'); @@ -94,6 +181,13 @@ SELECT pg_get_domain_ddl('regress_precise_numeric'); CREATE DOMAIN public.regress_precise_numeric AS numeric DEFAULT 0.00; (1 row) +SELECT pg_get_domain_ddl('regress_precise_numeric', pretty => true); + pg_get_domain_ddl +--------------------------------------------------------- + CREATE DOMAIN public.regress_precise_numeric AS numeric+ + DEFAULT 0.00; +(1 row) + -- Test domain over array type CREATE DOMAIN regress_int_array_domain AS int[] CHECK (array_length(VALUE, 1) <= 5); SELECT pg_get_domain_ddl('regress_int_array_domain'); @@ -102,6 +196,14 @@ SELECT pg_get_domain_ddl('regress_int_array_domain'); CREATE DOMAIN public.regress_int_array_domain AS integer[] CONSTRAINT regress_int_array_domain_check CHECK ((array_length(VALUE, 1) <= 5)); (1 row) +SELECT pg_get_domain_ddl('regress_int_array_domain', pretty => true); + pg_get_domain_ddl +------------------------------------------------------------ + CREATE DOMAIN public.regress_int_array_domain AS integer[]+ + CONSTRAINT regress_int_array_domain_check + + CHECK (array_length(VALUE, 1) <= 5); +(1 row) + -- Test domain in non-public schema CREATE SCHEMA regress_test_schema; CREATE DOMAIN regress_test_schema.regress_schema_domain AS text DEFAULT 'test'; @@ -123,6 +225,19 @@ SELECT pg_get_domain_ddl('regress_comprehensive_domain'); CREATE DOMAIN public.regress_comprehensive_domain AS character varying DEFAULT 'default_value'::character varying CONSTRAINT regress_comprehensive_domain_not_null NOT NULL CONSTRAINT regress_comprehensive_domain_check CHECK ((length((VALUE)::text) >= 5)) CONSTRAINT regress_comprehensive_domain_check1 CHECK (((VALUE)::text !~ '^\s*$'::text)); (1 row) +SELECT pg_get_domain_ddl('regress_comprehensive_domain', pretty => true); + pg_get_domain_ddl +------------------------------------------------------------------------ + CREATE DOMAIN public.regress_comprehensive_domain AS character varying+ + DEFAULT 'default_value'::character varying + + CONSTRAINT regress_comprehensive_domain_not_null + + NOT NULL + + CONSTRAINT regress_comprehensive_domain_check + + CHECK (length(VALUE::text) >= 5) + + CONSTRAINT regress_comprehensive_domain_check1 + + CHECK (VALUE::text !~ '^\s*$'::text); +(1 row) + -- Test domain over composite type CREATE TYPE regress_address_type AS (street text, city text, zipcode text); CREATE DOMAIN regress_address_domain AS regress_address_type CHECK ((VALUE).zipcode ~ '^\d{5}$'); @@ -132,6 +247,14 @@ SELECT pg_get_domain_ddl('regress_address_domain'); CREATE DOMAIN public.regress_address_domain AS regress_address_type CONSTRAINT regress_address_domain_check CHECK (((VALUE).zipcode ~ '^\d{5}$'::text)); (1 row) +SELECT pg_get_domain_ddl('regress_address_domain', pretty => true); + pg_get_domain_ddl +--------------------------------------------------------------------- + CREATE DOMAIN public.regress_address_domain AS regress_address_type+ + CONSTRAINT regress_address_domain_check + + CHECK ((VALUE).zipcode ~ '^\d{5}$'::text); +(1 row) + -- Test domain with NOT VALID constraint CREATE DOMAIN regress_domain_not_valid AS int; ALTER DOMAIN regress_domain_not_valid ADD CONSTRAINT check_positive CHECK (VALUE > 0) NOT VALID; @@ -142,6 +265,13 @@ SELECT pg_get_domain_ddl('regress_domain_not_valid'); ALTER DOMAIN public.regress_domain_not_valid ADD CONSTRAINT check_positive CHECK ((VALUE > 0)) NOT VALID; (1 row) +SELECT pg_get_domain_ddl('regress_domain_not_valid', pretty => true); + pg_get_domain_ddl +--------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_domain_not_valid AS integer; + + ALTER DOMAIN public.regress_domain_not_valid ADD CONSTRAINT check_positive CHECK (VALUE > 0) NOT VALID; +(1 row) + -- Test domain with mix of valid and not valid constraints CREATE DOMAIN regress_domain_mixed AS int CHECK (VALUE != 0); ALTER DOMAIN regress_domain_mixed ADD CONSTRAINT check_range CHECK (VALUE BETWEEN 1 AND 100) NOT VALID; @@ -152,6 +282,15 @@ SELECT pg_get_domain_ddl('regress_domain_mixed'); ALTER DOMAIN public.regress_domain_mixed ADD CONSTRAINT check_range CHECK (((VALUE >= 1) AND (VALUE <= 100))) NOT VALID; (1 row) +SELECT pg_get_domain_ddl('regress_domain_mixed', pretty => true); + pg_get_domain_ddl +-------------------------------------------------------------------------------------------------------------------- + CREATE DOMAIN public.regress_domain_mixed AS integer + + CONSTRAINT regress_domain_mixed_check + + CHECK (VALUE <> 0); + + ALTER DOMAIN public.regress_domain_mixed ADD CONSTRAINT check_range CHECK (VALUE >= 1 AND VALUE <= 100) NOT VALID; +(1 row) + -- Test domain with collation CREATE DOMAIN regress_domain_with_collate AS text COLLATE "C"; SELECT pg_get_domain_ddl('regress_domain_with_collate'); @@ -160,6 +299,13 @@ SELECT pg_get_domain_ddl('regress_domain_with_collate'); CREATE DOMAIN public.regress_domain_with_collate AS text COLLATE "C"; (1 row) +SELECT pg_get_domain_ddl('regress_domain_with_collate', pretty => true); + pg_get_domain_ddl +---------------------------------------------------------- + CREATE DOMAIN public.regress_domain_with_collate AS text+ + COLLATE "C"; +(1 row) + -- Cleanup DROP DOMAIN regress_us_postal_code; DROP DOMAIN regress_domain_not_null; diff --git a/src/test/regress/sql/object_ddl.sql b/src/test/regress/sql/object_ddl.sql index aa2ab62c1934b..98fb20017eaad 100644 --- a/src/test/regress/sql/object_ddl.sql +++ b/src/test/regress/sql/object_ddl.sql @@ -12,11 +12,16 @@ CREATE DOMAIN regress_us_postal_code AS TEXT ); SELECT pg_get_domain_ddl('regress_us_postal_code'); +SELECT pg_get_domain_ddl('regress_us_postal_code', pretty => false); +SELECT pg_get_domain_ddl('regress_us_postal_code', false); +SELECT pg_get_domain_ddl('regress_us_postal_code', pretty => true); +SELECT pg_get_domain_ddl('regress_us_postal_code', true); CREATE DOMAIN regress_domain_not_null AS INT NOT NULL; SELECT pg_get_domain_ddl('regress_domain_not_null'); +SELECT pg_get_domain_ddl('regress_domain_not_null', pretty => true); CREATE DOMAIN regress_domain_check AS INT @@ -24,6 +29,7 @@ CREATE DOMAIN regress_domain_check AS INT CONSTRAINT regress_b CHECK (VALUE > 10); SELECT pg_get_domain_ddl('regress_domain_check'); +SELECT pg_get_domain_ddl('regress_domain_check', pretty => true); CREATE DOMAIN "regress_domain with space" AS INT @@ -32,24 +38,29 @@ CREATE DOMAIN "regress_domain with space" AS INT CONSTRAINT "regress_ConstraintC" CHECK (VALUE != 55); SELECT pg_get_domain_ddl('"regress_domain with space"'); +SELECT pg_get_domain_ddl('"regress_domain with space"', pretty => true); -- Test error cases SELECT pg_get_domain_ddl('regress_nonexistent_domain'::regtype); -- should fail SELECT pg_get_domain_ddl(NULL); -- should return NULL +SELECT pg_get_domain_ddl(NULL, pretty => true); -- should return NULL -- Test domains with no constraints CREATE DOMAIN regress_simple_domain AS text; SELECT pg_get_domain_ddl('regress_simple_domain'); +SELECT pg_get_domain_ddl('regress_simple_domain', pretty => true); -- Test domain over another domain CREATE DOMAIN regress_base_domain AS varchar(10); CREATE DOMAIN regress_derived_domain AS regress_base_domain CHECK (LENGTH(VALUE) > 3); SELECT pg_get_domain_ddl('regress_derived_domain'); +SELECT pg_get_domain_ddl('regress_derived_domain', pretty => true); -- Test domain with complex default expressions CREATE SEQUENCE regress_test_seq; CREATE DOMAIN regress_seq_domain AS int DEFAULT nextval('regress_test_seq'); SELECT pg_get_domain_ddl('regress_seq_domain'); +SELECT pg_get_domain_ddl('regress_seq_domain', pretty => true); -- Test domain with a renamed sequence as default expression ALTER SEQUENCE regress_test_seq RENAME TO regress_test_seq_renamed; @@ -58,10 +69,12 @@ SELECT pg_get_domain_ddl('regress_seq_domain'); -- Test domain with type modifiers CREATE DOMAIN regress_precise_numeric AS numeric(10,2) DEFAULT 0.00; SELECT pg_get_domain_ddl('regress_precise_numeric'); +SELECT pg_get_domain_ddl('regress_precise_numeric', pretty => true); -- Test domain over array type CREATE DOMAIN regress_int_array_domain AS int[] CHECK (array_length(VALUE, 1) <= 5); SELECT pg_get_domain_ddl('regress_int_array_domain'); +SELECT pg_get_domain_ddl('regress_int_array_domain', pretty => true); -- Test domain in non-public schema CREATE SCHEMA regress_test_schema; @@ -75,25 +88,30 @@ CREATE DOMAIN regress_comprehensive_domain AS varchar(50) CHECK (LENGTH(VALUE) >= 5) CHECK (VALUE !~ '^\s*$'); -- not just whitespace SELECT pg_get_domain_ddl('regress_comprehensive_domain'); +SELECT pg_get_domain_ddl('regress_comprehensive_domain', pretty => true); -- Test domain over composite type CREATE TYPE regress_address_type AS (street text, city text, zipcode text); CREATE DOMAIN regress_address_domain AS regress_address_type CHECK ((VALUE).zipcode ~ '^\d{5}$'); SELECT pg_get_domain_ddl('regress_address_domain'); +SELECT pg_get_domain_ddl('regress_address_domain', pretty => true); -- Test domain with NOT VALID constraint CREATE DOMAIN regress_domain_not_valid AS int; ALTER DOMAIN regress_domain_not_valid ADD CONSTRAINT check_positive CHECK (VALUE > 0) NOT VALID; SELECT pg_get_domain_ddl('regress_domain_not_valid'); +SELECT pg_get_domain_ddl('regress_domain_not_valid', pretty => true); -- Test domain with mix of valid and not valid constraints CREATE DOMAIN regress_domain_mixed AS int CHECK (VALUE != 0); ALTER DOMAIN regress_domain_mixed ADD CONSTRAINT check_range CHECK (VALUE BETWEEN 1 AND 100) NOT VALID; SELECT pg_get_domain_ddl('regress_domain_mixed'); +SELECT pg_get_domain_ddl('regress_domain_mixed', pretty => true); -- Test domain with collation CREATE DOMAIN regress_domain_with_collate AS text COLLATE "C"; SELECT pg_get_domain_ddl('regress_domain_with_collate'); +SELECT pg_get_domain_ddl('regress_domain_with_collate', pretty => true); -- Cleanup DROP DOMAIN regress_us_postal_code;