aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-03-01 11:37:46 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-03-01 11:37:46 -0500
commit8f72a5704854d292065886eb47ba18fbd504113e (patch)
tree5abf1c9c9de417cf9830fd9890a80e124bbc0236 /src
parent1437824564f47e8e7641e98958a08c1544b6b8f4 (diff)
downloadpostgresql-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.c30
-rw-r--r--src/test/regress/expected/create_type.out20
-rw-r--r--src/test/regress/sql/create_type.sql6
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);