Skip to content

Commit a26116c

Browse files
committed
Refactor format_type APIs to be more modular
Introduce a new format_type_extended, with a flags bitmask argument that can modify the default behavior. A few compatibility and readability wrappers remain: format_type_be format_type_be_qualified format_type_with_typemod while format_type_with_typemod_qualified, which had a single caller, is removed. Author: Michael Paquier, some revisions by me Discussion: 20180213035107.GA2915@paquier.xyz
1 parent cef6004 commit a26116c

File tree

3 files changed

+81
-72
lines changed

3 files changed

+81
-72
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -854,10 +854,12 @@ foreign_expr_walker(Node *node,
854854
static char *
855855
deparse_type_name(Oid type_oid, int32 typemod)
856856
{
857-
if (is_builtin(type_oid))
858-
return format_type_with_typemod(type_oid, typemod);
859-
else
860-
return format_type_with_typemod_qualified(type_oid, typemod);
857+
uint8 flags = FORMAT_TYPE_TYPEMOD_GIVEN;
858+
859+
if (!is_builtin(type_oid))
860+
flags |= FORMAT_TYPE_FORCE_QUALIFY;
861+
862+
return format_type_extended(type_oid, typemod, flags);
861863
}
862864

863865
/*

src/backend/utils/adt/format_type.c

Lines changed: 67 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
#define MAX_INT32_LEN 11
3030

31-
static char *format_type_internal(Oid type_oid, int32 typemod,
32-
bool typemod_given, bool allow_invalid,
33-
bool force_qualify);
3431
static char *printTypmod(const char *typname, int32 typmod, Oid typmodout);
3532

3633

@@ -72,81 +69,52 @@ format_type(PG_FUNCTION_ARGS)
7269
PG_RETURN_NULL();
7370

7471
type_oid = PG_GETARG_OID(0);
72+
typemod = PG_ARGISNULL(1) ? -1 : PG_GETARG_INT32(1);
7573

76-
if (PG_ARGISNULL(1))
77-
result = format_type_internal(type_oid, -1, false, true, false);
78-
else
79-
{
80-
typemod = PG_GETARG_INT32(1);
81-
result = format_type_internal(type_oid, typemod, true, true, false);
82-
}
74+
result = format_type_extended(type_oid, typemod,
75+
FORMAT_TYPE_TYPEMOD_GIVEN |
76+
FORMAT_TYPE_ALLOW_INVALID);
8377

8478
PG_RETURN_TEXT_P(cstring_to_text(result));
8579
}
8680

8781
/*
88-
* This version is for use within the backend in error messages, etc.
89-
* One difference is that it will fail for an invalid type.
82+
* format_type_extended
83+
* Generate a possibly-qualified type name.
9084
*
91-
* The result is always a palloc'd string.
92-
*/
93-
char *
94-
format_type_be(Oid type_oid)
95-
{
96-
return format_type_internal(type_oid, -1, false, false, false);
97-
}
98-
99-
/*
100-
* This version returns a name that is always qualified (unless it's one
101-
* of the SQL-keyword type names, such as TIMESTAMP WITH TIME ZONE).
102-
*/
103-
char *
104-
format_type_be_qualified(Oid type_oid)
105-
{
106-
return format_type_internal(type_oid, -1, false, false, true);
107-
}
108-
109-
/*
110-
* This version allows a nondefault typemod to be specified.
111-
*/
112-
char *
113-
format_type_with_typemod(Oid type_oid, int32 typemod)
114-
{
115-
return format_type_internal(type_oid, typemod, true, false, false);
116-
}
117-
118-
/*
119-
* This version allows a nondefault typemod to be specified, and forces
120-
* qualification of normal type names.
85+
* The default is to only qualify if the type is not in the search path, to
86+
* ignore the given typmod, and to raise an error if a non-existent type_oid is
87+
* given.
88+
*
89+
* The following bits in 'flags' modify the behavior:
90+
* - FORMAT_TYPE_TYPEMOD_GIVEN
91+
* consider the given typmod in the output (may be -1 to request
92+
* the default behavior)
93+
*
94+
* - FORMAT_TYPE_ALLOW_INVALID
95+
* if the type OID is invalid or unknown, return ??? or such instead
96+
* of failing
97+
*
98+
* - FORMAT_TYPE_FORCE_QUALIFY
99+
* always schema-qualify type names, regardless of search_path
121100
*/
122101
char *
123-
format_type_with_typemod_qualified(Oid type_oid, int32 typemod)
102+
format_type_extended(Oid type_oid, int32 typemod, bits16 flags)
124103
{
125-
return format_type_internal(type_oid, typemod, true, false, true);
126-
}
127-
128-
/*
129-
* Common workhorse.
130-
*/
131-
static char *
132-
format_type_internal(Oid type_oid, int32 typemod,
133-
bool typemod_given, bool allow_invalid,
134-
bool force_qualify)
135-
{
136-
bool with_typemod = typemod_given && (typemod >= 0);
137104
HeapTuple tuple;
138105
Form_pg_type typeform;
139106
Oid array_base_type;
140107
bool is_array;
141108
char *buf;
109+
bool with_typemod;
142110

143-
if (type_oid == InvalidOid && allow_invalid)
111+
if (type_oid == InvalidOid && (flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
144112
return pstrdup("-");
145113

146114
tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid));
147115
if (!HeapTupleIsValid(tuple))
148116
{
149-
if (allow_invalid)
117+
if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
150118
return pstrdup("???");
151119
else
152120
elog(ERROR, "cache lookup failed for type %u", type_oid);
@@ -162,15 +130,14 @@ format_type_internal(Oid type_oid, int32 typemod,
162130
*/
163131
array_base_type = typeform->typelem;
164132

165-
if (array_base_type != InvalidOid &&
166-
typeform->typstorage != 'p')
133+
if (array_base_type != InvalidOid && typeform->typstorage != 'p')
167134
{
168135
/* Switch our attention to the array element type */
169136
ReleaseSysCache(tuple);
170137
tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(array_base_type));
171138
if (!HeapTupleIsValid(tuple))
172139
{
173-
if (allow_invalid)
140+
if ((flags & FORMAT_TYPE_ALLOW_INVALID) != 0)
174141
return pstrdup("???[]");
175142
else
176143
elog(ERROR, "cache lookup failed for type %u", type_oid);
@@ -182,6 +149,8 @@ format_type_internal(Oid type_oid, int32 typemod,
182149
else
183150
is_array = false;
184151

152+
with_typemod = (flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0 && (typemod >= 0);
153+
185154
/*
186155
* See if we want to special-case the output for certain built-in types.
187156
* Note that these special cases should all correspond to special
@@ -200,7 +169,7 @@ format_type_internal(Oid type_oid, int32 typemod,
200169
case BITOID:
201170
if (with_typemod)
202171
buf = printTypmod("bit", typemod, typeform->typmodout);
203-
else if (typemod_given)
172+
else if ((flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0)
204173
{
205174
/*
206175
* bit with typmod -1 is not the same as BIT, which means
@@ -219,7 +188,7 @@ format_type_internal(Oid type_oid, int32 typemod,
219188
case BPCHAROID:
220189
if (with_typemod)
221190
buf = printTypmod("character", typemod, typeform->typmodout);
222-
else if (typemod_given)
191+
else if ((flags & FORMAT_TYPE_TYPEMOD_GIVEN) != 0)
223192
{
224193
/*
225194
* bpchar with typmod -1 is not the same as CHARACTER, which
@@ -313,13 +282,14 @@ format_type_internal(Oid type_oid, int32 typemod,
313282
/*
314283
* Default handling: report the name as it appears in the catalog.
315284
* Here, we must qualify the name if it is not visible in the search
316-
* path, and we must double-quote it if it's not a standard identifier
317-
* or if it matches any keyword.
285+
* path or if caller requests it; and we must double-quote it if it's
286+
* not a standard identifier or if it matches any keyword.
318287
*/
319288
char *nspname;
320289
char *typname;
321290

322-
if (!force_qualify && TypeIsVisible(type_oid))
291+
if ((flags & FORMAT_TYPE_FORCE_QUALIFY) == 0 &&
292+
TypeIsVisible(type_oid))
323293
nspname = NULL;
324294
else
325295
nspname = get_namespace_name_or_temp(typeform->typnamespace);
@@ -340,6 +310,36 @@ format_type_internal(Oid type_oid, int32 typemod,
340310
return buf;
341311
}
342312

313+
/*
314+
* This version is for use within the backend in error messages, etc.
315+
* One difference is that it will fail for an invalid type.
316+
*
317+
* The result is always a palloc'd string.
318+
*/
319+
char *
320+
format_type_be(Oid type_oid)
321+
{
322+
return format_type_extended(type_oid, -1, 0);
323+
}
324+
325+
/*
326+
* This version returns a name that is always qualified (unless it's one
327+
* of the SQL-keyword type names, such as TIMESTAMP WITH TIME ZONE).
328+
*/
329+
char *
330+
format_type_be_qualified(Oid type_oid)
331+
{
332+
return format_type_extended(type_oid, -1, FORMAT_TYPE_FORCE_QUALIFY);
333+
}
334+
335+
/*
336+
* This version allows a nondefault typemod to be specified.
337+
*/
338+
char *
339+
format_type_with_typemod(Oid type_oid, int32 typemod)
340+
{
341+
return format_type_extended(type_oid, typemod, FORMAT_TYPE_TYPEMOD_GIVEN);
342+
}
343343

344344
/*
345345
* Add typmod decoration to the basic type name
@@ -437,8 +437,8 @@ oidvectortypes(PG_FUNCTION_ARGS)
437437

438438
for (num = 0; num < numargs; num++)
439439
{
440-
char *typename = format_type_internal(oidArray->values[num], -1,
441-
false, true, false);
440+
char *typename = format_type_extended(oidArray->values[num], -1,
441+
FORMAT_TYPE_ALLOW_INVALID);
442442
size_t slen = strlen(typename);
443443

444444
if (left < (slen + 2))

src/include/utils/builtins.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,17 @@ extern void clean_ipv6_addr(int addr_family, char *addr);
112112
extern Datum numeric_float8_no_overflow(PG_FUNCTION_ARGS);
113113

114114
/* format_type.c */
115+
116+
/* Control flags for format_type_extended */
117+
#define FORMAT_TYPE_TYPEMOD_GIVEN 0x01 /* typemod defined by caller */
118+
#define FORMAT_TYPE_ALLOW_INVALID 0x02 /* allow invalid types */
119+
#define FORMAT_TYPE_FORCE_QUALIFY 0x04 /* force qualification of type */
120+
extern char *format_type_extended(Oid type_oid, int32 typemod, bits16 flags);
121+
115122
extern char *format_type_be(Oid type_oid);
116123
extern char *format_type_be_qualified(Oid type_oid);
117124
extern char *format_type_with_typemod(Oid type_oid, int32 typemod);
118-
extern char *format_type_with_typemod_qualified(Oid type_oid, int32 typemod);
125+
119126
extern int32 type_maximum_size(Oid type_oid, int32 typemod);
120127

121128
/* quote.c */

0 commit comments

Comments
 (0)