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 );
3431static 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 */
122101char *
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 ))
0 commit comments