Commit 8f72a570 authored by Tom Lane's avatar Tom Lane

Fix format_type() to restore its old behavior.

Commit a26116c6 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
parent 14378245
...@@ -854,7 +854,7 @@ foreign_expr_walker(Node *node, ...@@ -854,7 +854,7 @@ foreign_expr_walker(Node *node,
static char * static char *
deparse_type_name(Oid type_oid, int32 typemod) deparse_type_name(Oid type_oid, int32 typemod)
{ {
uint8 flags = FORMAT_TYPE_TYPEMOD_GIVEN; bits16 flags = FORMAT_TYPE_TYPEMOD_GIVEN;
if (!is_builtin(type_oid)) if (!is_builtin(type_oid))
flags |= FORMAT_TYPE_FORCE_QUALIFY; flags |= FORMAT_TYPE_FORCE_QUALIFY;
......
...@@ -63,17 +63,23 @@ format_type(PG_FUNCTION_ARGS) ...@@ -63,17 +63,23 @@ format_type(PG_FUNCTION_ARGS)
Oid type_oid; Oid type_oid;
int32 typemod; int32 typemod;
char *result; char *result;
bits16 flags = FORMAT_TYPE_ALLOW_INVALID;
/* Since this function is not strict, we must test for null args */ /* Since this function is not strict, we must test for null args */
if (PG_ARGISNULL(0)) if (PG_ARGISNULL(0))
PG_RETURN_NULL(); PG_RETURN_NULL();
type_oid = PG_GETARG_OID(0); type_oid = PG_GETARG_OID(0);
typemod = PG_ARGISNULL(1) ? -1 : PG_GETARG_INT32(1);
result = format_type_extended(type_oid, typemod, if (PG_ARGISNULL(1))
FORMAT_TYPE_TYPEMOD_GIVEN | typemod = -1;
FORMAT_TYPE_ALLOW_INVALID); 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)); PG_RETURN_TEXT_P(cstring_to_text(result));
} }
...@@ -82,21 +88,23 @@ format_type(PG_FUNCTION_ARGS) ...@@ -82,21 +88,23 @@ format_type(PG_FUNCTION_ARGS)
* format_type_extended * format_type_extended
* Generate a possibly-qualified type name. * Generate a possibly-qualified type name.
* *
* The default is to only qualify if the type is not in the search path, to * The default behavior is to only qualify if the type is not in the search
* ignore the given typmod, and to raise an error if a non-existent type_oid is * path, to ignore the given typmod, and to raise an error if a non-existent
* given. * type_oid is given.
* *
* The following bits in 'flags' modify the behavior: * The following bits in 'flags' modify the behavior:
* - FORMAT_TYPE_TYPEMOD_GIVEN * - FORMAT_TYPE_TYPEMOD_GIVEN
* consider the given typmod in the output (may be -1 to request * include the typmod in the output (typmod could still be -1 though)
* the default behavior)
*
* - FORMAT_TYPE_ALLOW_INVALID * - FORMAT_TYPE_ALLOW_INVALID
* if the type OID is invalid or unknown, return ??? or such instead * if the type OID is invalid or unknown, return ??? or such instead
* of failing * of failing
*
* - FORMAT_TYPE_FORCE_QUALIFY * - FORMAT_TYPE_FORCE_QUALIFY
* always schema-qualify type names, regardless of search_path * 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 * char *
format_type_extended(Oid type_oid, int32 typemod, bits16 flags) format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
......
...@@ -191,3 +191,23 @@ TABLE mytab; ...@@ -191,3 +191,23 @@ TABLE mytab;
(-44,5.5,12) (-44,5.5,12)
(2 rows) (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)
...@@ -148,3 +148,9 @@ WHERE attrelid = 'mytab'::regclass AND attnum > 0; ...@@ -148,3 +148,9 @@ WHERE attrelid = 'mytab'::regclass AND attnum > 0;
-- might as well exercise the widget type while we're here -- might as well exercise the widget type while we're here
INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)'); INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)');
TABLE mytab; 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment