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/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 ca2d162370b57..54e2608382814 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 @@ -546,6 +550,11 @@ 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 ") @@ -13739,6 +13748,37 @@ 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) + { + appendStringInfoChar(buf, '\n'); + /* 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); +} + /* * Helper function to scan domain constraints @@ -13787,7 +13827,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; @@ -13814,16 +13854,17 @@ 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)); } } /* Add default value if present */ if (defaultExpr != NULL) { - char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, 0, 0); - appendStringInfo(buf, " DEFAULT %s", defaultValue); + char *defaultValue = deparse_expression_pretty(defaultExpr, NIL, false, false, prettyFlags, 0); + + get_formatted_string(buf, prettyFlags, 1, "DEFAULT %s", defaultValue); } /* Add valid constraints */ @@ -13837,14 +13878,14 @@ 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); + 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); } @@ -13856,14 +13897,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); @@ -13871,13 +13912,30 @@ add_alter_domain_statements(StringInfo buf, List *invalidConstraints) } /* - * pg_get_domain_ddl - Get CREATE DOMAIN statement for a domain + * pg_get_domain_ddl_ext - Get CREATE DOMAIN statement for a domain with pretty-print option */ Datum -pg_get_domain_ddl(PG_FUNCTION_ARGS) +pg_get_domain_ddl_ext(PG_FUNCTION_ARGS) { - StringInfoData buf; Oid domain_oid = PG_GETARG_OID(0); + bool pretty = PG_GETARG_BOOL(1); + char *res; + int prettyFlags; + + prettyFlags = GET_DDL_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,7 +13945,7 @@ 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); @@ -13899,16 +13957,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..49cfb6c1df22f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8515,9 +8515,9 @@ { 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', +{ oid => '8024', descr => 'get CREATE statement for DOMAIN with pretty option', proname => 'pg_get_domain_ddl', prorettype => 'text', - proargtypes => 'regtype', prosrc => 'pg_get_domain_ddl' }, + 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', diff --git a/src/test/regress/expected/object_ddl.out b/src/test/regress/expected/object_ddl.out index 3dc1f1bc04963..a72109ab9fbac 100644 --- a/src/test/regress/expected/object_ddl.out +++ b/src/test/regress/expected/object_ddl.out @@ -10,9 +10,39 @@ 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) + +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; @@ -22,13 +52,31 @@ 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); 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) + +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 @@ -36,9 +84,21 @@ 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) + +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 @@ -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,13 +126,27 @@ 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); 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) + +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 @@ -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,12 +181,27 @@ 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'); - 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) + +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 @@ -118,24 +220,52 @@ 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) + +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}$'); 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) + +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; 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; +(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; + @@ -146,9 +276,18 @@ SELECT pg_get_domain_ddl('regress_domain_not_valid'); 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; +(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); + + 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) @@ -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;