diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2018-03-01 11:37:46 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2018-03-01 11:37:46 -0500 |
commit | 8f72a5704854d292065886eb47ba18fbd504113e (patch) | |
tree | 5abf1c9c9de417cf9830fd9890a80e124bbc0236 /src | |
parent | 1437824564f47e8e7641e98958a08c1544b6b8f4 (diff) | |
download | postgresql-8f72a5704854d292065886eb47ba18fbd504113e.tar.gz postgresql-8f72a5704854d292065886eb47ba18fbd504113e.zip |
Fix format_type() to restore its old behavior.
Commit a26116c6c accidentally changed the behavior of the SQL format_type()
function while refactoring. For the reasons explained in that function's
comment, a NULL typemod argument should behave differently from a -1
argument. Since we've managed to break this, add a regression test
memorializing the intended behavior.
In passing, be consistent about the type of the "flags" parameter.
Noted by Rushabh Lathia, though I revised the patch some more.
Discussion: https://postgr.es/m/CAGPqQf3RB2q-d2Awp_-x-Ur6aOxTUwnApt-vm-iTtceZxYnePg@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/format_type.c | 30 | ||||
-rw-r--r-- | src/test/regress/expected/create_type.out | 20 | ||||
-rw-r--r-- | src/test/regress/sql/create_type.sql | 6 |
3 files changed, 45 insertions, 11 deletions
diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c index 872574fdd54..f1f0ba3e0b3 100644 --- a/src/backend/utils/adt/format_type.c +++ b/src/backend/utils/adt/format_type.c @@ -63,17 +63,23 @@ format_type(PG_FUNCTION_ARGS) Oid type_oid; int32 typemod; char *result; + bits16 flags = FORMAT_TYPE_ALLOW_INVALID; /* Since this function is not strict, we must test for null args */ if (PG_ARGISNULL(0)) PG_RETURN_NULL(); type_oid = PG_GETARG_OID(0); - typemod = PG_ARGISNULL(1) ? -1 : PG_GETARG_INT32(1); - result = format_type_extended(type_oid, typemod, - FORMAT_TYPE_TYPEMOD_GIVEN | - FORMAT_TYPE_ALLOW_INVALID); + if (PG_ARGISNULL(1)) + typemod = -1; + else + { + typemod = PG_GETARG_INT32(1); + flags |= FORMAT_TYPE_TYPEMOD_GIVEN; + } + + result = format_type_extended(type_oid, typemod, flags); PG_RETURN_TEXT_P(cstring_to_text(result)); } @@ -82,21 +88,23 @@ format_type(PG_FUNCTION_ARGS) * format_type_extended * Generate a possibly-qualified type name. * - * The default is to only qualify if the type is not in the search path, to - * ignore the given typmod, and to raise an error if a non-existent type_oid is - * given. + * The default behavior is to only qualify if the type is not in the search + * path, to ignore the given typmod, and to raise an error if a non-existent + * type_oid is given. * * The following bits in 'flags' modify the behavior: * - FORMAT_TYPE_TYPEMOD_GIVEN - * consider the given typmod in the output (may be -1 to request - * the default behavior) - * + * include the typmod in the output (typmod could still be -1 though) * - FORMAT_TYPE_ALLOW_INVALID * if the type OID is invalid or unknown, return ??? or such instead * of failing - * * - FORMAT_TYPE_FORCE_QUALIFY * always schema-qualify type names, regardless of search_path + * + * Note that TYPEMOD_GIVEN is not interchangeable with "typemod == -1"; + * see the comments above for format_type(). + * + * Returns a palloc'd string. */ char * format_type_extended(Oid type_oid, int32 typemod, bits16 flags) diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out index 0ab85a883c0..2f7d5f94d7b 100644 --- a/src/test/regress/expected/create_type.out +++ b/src/test/regress/expected/create_type.out @@ -191,3 +191,23 @@ TABLE mytab; (-44,5.5,12) (2 rows) +-- and test format_type() a bit more, too +select format_type('varchar'::regtype, 42); + format_type +----------------------- + character varying(38) +(1 row) + +select format_type('bpchar'::regtype, null); + format_type +------------- + character +(1 row) + +-- this behavior difference is intentional +select format_type('bpchar'::regtype, -1); + format_type +------------- + bpchar +(1 row) + diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql index 07061bc02a6..3d1deba97cf 100644 --- a/src/test/regress/sql/create_type.sql +++ b/src/test/regress/sql/create_type.sql @@ -148,3 +148,9 @@ WHERE attrelid = 'mytab'::regclass AND attnum > 0; -- might as well exercise the widget type while we're here INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)'); TABLE mytab; + +-- and test format_type() a bit more, too +select format_type('varchar'::regtype, 42); +select format_type('bpchar'::regtype, null); +-- this behavior difference is intentional +select format_type('bpchar'::regtype, -1); |