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,
static char *
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))
flags |= FORMAT_TYPE_FORCE_QUALIFY;
......
......@@ -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)
......
......@@ -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)
......@@ -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);
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