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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy