28
28
29
29
#define MAX_INT32_LEN 11
30
30
31
- static char * format_type_internal (Oid type_oid , int32 typemod ,
32
- bool typemod_given , bool allow_invalid ,
33
- bool force_qualify );
34
31
static char * printTypmod (const char * typname , int32 typmod , Oid typmodout );
35
32
36
33
@@ -72,81 +69,52 @@ format_type(PG_FUNCTION_ARGS)
72
69
PG_RETURN_NULL ();
73
70
74
71
type_oid = PG_GETARG_OID (0 );
72
+ typemod = PG_ARGISNULL (1 ) ? -1 : PG_GETARG_INT32 (1 );
75
73
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 );
83
77
84
78
PG_RETURN_TEXT_P (cstring_to_text (result ));
85
79
}
86
80
87
81
/*
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 .
90
84
*
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
121
100
*/
122
101
char *
123
- format_type_with_typemod_qualified (Oid type_oid , int32 typemod )
102
+ format_type_extended (Oid type_oid , int32 typemod , bits16 flags )
124
103
{
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 );
137
104
HeapTuple tuple ;
138
105
Form_pg_type typeform ;
139
106
Oid array_base_type ;
140
107
bool is_array ;
141
108
char * buf ;
109
+ bool with_typemod ;
142
110
143
- if (type_oid == InvalidOid && allow_invalid )
111
+ if (type_oid == InvalidOid && ( flags & FORMAT_TYPE_ALLOW_INVALID ) != 0 )
144
112
return pstrdup ("-" );
145
113
146
114
tuple = SearchSysCache1 (TYPEOID , ObjectIdGetDatum (type_oid ));
147
115
if (!HeapTupleIsValid (tuple ))
148
116
{
149
- if (allow_invalid )
117
+ if (( flags & FORMAT_TYPE_ALLOW_INVALID ) != 0 )
150
118
return pstrdup ("???" );
151
119
else
152
120
elog (ERROR , "cache lookup failed for type %u" , type_oid );
@@ -162,15 +130,14 @@ format_type_internal(Oid type_oid, int32 typemod,
162
130
*/
163
131
array_base_type = typeform -> typelem ;
164
132
165
- if (array_base_type != InvalidOid &&
166
- typeform -> typstorage != 'p' )
133
+ if (array_base_type != InvalidOid && typeform -> typstorage != 'p' )
167
134
{
168
135
/* Switch our attention to the array element type */
169
136
ReleaseSysCache (tuple );
170
137
tuple = SearchSysCache1 (TYPEOID , ObjectIdGetDatum (array_base_type ));
171
138
if (!HeapTupleIsValid (tuple ))
172
139
{
173
- if (allow_invalid )
140
+ if (( flags & FORMAT_TYPE_ALLOW_INVALID ) != 0 )
174
141
return pstrdup ("???[]" );
175
142
else
176
143
elog (ERROR , "cache lookup failed for type %u" , type_oid );
@@ -182,6 +149,8 @@ format_type_internal(Oid type_oid, int32 typemod,
182
149
else
183
150
is_array = false;
184
151
152
+ with_typemod = (flags & FORMAT_TYPE_TYPEMOD_GIVEN ) != 0 && (typemod >= 0 );
153
+
185
154
/*
186
155
* See if we want to special-case the output for certain built-in types.
187
156
* Note that these special cases should all correspond to special
@@ -200,7 +169,7 @@ format_type_internal(Oid type_oid, int32 typemod,
200
169
case BITOID :
201
170
if (with_typemod )
202
171
buf = printTypmod ("bit" , typemod , typeform -> typmodout );
203
- else if (typemod_given )
172
+ else if (( flags & FORMAT_TYPE_TYPEMOD_GIVEN ) != 0 )
204
173
{
205
174
/*
206
175
* bit with typmod -1 is not the same as BIT, which means
@@ -219,7 +188,7 @@ format_type_internal(Oid type_oid, int32 typemod,
219
188
case BPCHAROID :
220
189
if (with_typemod )
221
190
buf = printTypmod ("character" , typemod , typeform -> typmodout );
222
- else if (typemod_given )
191
+ else if (( flags & FORMAT_TYPE_TYPEMOD_GIVEN ) != 0 )
223
192
{
224
193
/*
225
194
* bpchar with typmod -1 is not the same as CHARACTER, which
@@ -313,13 +282,14 @@ format_type_internal(Oid type_oid, int32 typemod,
313
282
/*
314
283
* Default handling: report the name as it appears in the catalog.
315
284
* 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.
318
287
*/
319
288
char * nspname ;
320
289
char * typname ;
321
290
322
- if (!force_qualify && TypeIsVisible (type_oid ))
291
+ if ((flags & FORMAT_TYPE_FORCE_QUALIFY ) == 0 &&
292
+ TypeIsVisible (type_oid ))
323
293
nspname = NULL ;
324
294
else
325
295
nspname = get_namespace_name_or_temp (typeform -> typnamespace );
@@ -340,6 +310,36 @@ format_type_internal(Oid type_oid, int32 typemod,
340
310
return buf ;
341
311
}
342
312
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
+ }
343
343
344
344
/*
345
345
* Add typmod decoration to the basic type name
@@ -437,8 +437,8 @@ oidvectortypes(PG_FUNCTION_ARGS)
437
437
438
438
for (num = 0 ; num < numargs ; num ++ )
439
439
{
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 );
442
442
size_t slen = strlen (typename );
443
443
444
444
if (left < (slen + 2 ))
0 commit comments