<tbody>
<row>
- <entry role="func_table_entry"><para role="func_signature">
+ <entry id="format-type" xreflabel="format_type" role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>format_type</primary>
</indexterm>
OID for comparison purposes but displays as a type name.
</para>
<para>
- For example:
-<programlisting>
-SELECT pg_typeof(33);
- pg_typeof
------------
- integer
-
-SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
- typlen
---------
- 4
-</programlisting>
+ <literal>pg_typeof(33)</literal>
+ <returnvalue>integer</returnvalue>
</para></entry>
</row>
collatable data type, then an error is raised.
</para>
<para>
- For example:
-<programlisting>
-SELECT collation for (description) FROM pg_description LIMIT 1;
- pg_collation_for
-------------------
- "default"
-
-SELECT collation for ('foo' COLLATE "de_DE");
- pg_collation_for
-------------------
- "de_DE"
-</programlisting>
+ <literal>collation for ('foo'::text)</literal>
+ <returnvalue>"default"</returnvalue>
+ </para>
+ <para>
+ <literal>collation for ('foo' COLLATE "de_DE")</literal>
+ <returnvalue>"de_DE"</returnvalue>
</para></entry>
</row>
</row>
<row>
- <entry role="func_table_entry"><para role="func_signature">
+ <entry id="to-regtype" xreflabel="to_regtype" role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>to_regtype</primary>
</indexterm>
<returnvalue>regtype</returnvalue>
</para>
<para>
- Translates a textual type name to its OID. A similar result is
- obtained by casting the string to type <type>regtype</type> (see
- <xref linkend="datatype-oid"/>); however, this function will return
- <literal>NULL</literal> rather than throwing an error if the name is
- not found.
+ Parses a string of text, extracts a potential type name from it,
+ and translates that name into a type OID. A syntax error in the
+ string will result in an error; but if the string is a
+ syntactically valid type name that happens not to be found in the
+ catalogs, the result is <literal>NULL</literal>. A similar result
+ is obtained by casting the string to type <type>regtype</type>
+ (see <xref linkend="datatype-oid"/>), except that that will throw
+ error for name not found.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regtypemod</primary>
+ </indexterm>
+ <function>to_regtypemod</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Parses a string of text, extracts a potential type name from it,
+ and translates its type modifier, if any. A syntax error in the
+ string will result in an error; but if the string is a
+ syntactically valid type name that happens not to be found in the
+ catalogs, the result is <literal>NULL</literal>. The result is
+ <literal>-1</literal> if no type modifier is present.
+ </para>
+ <para>
+ <function>to_regtypemod</function> can be combined with
+ <xref linkend="to-regtype"/> to produce appropriate inputs for
+ <xref linkend="format-type"/>, allowing a string representing a
+ type name to be canonicalized.
+ </para>
+ <para>
+ <literal>format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)'))</literal>
+ <returnvalue>character varying(32)</returnvalue>
</para></entry>
</row>
</tbody>
PG_RETURN_DATUM(result);
}
+/*
+ * to_regtypemod - converts "typename" to type modifier
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regtypemod(PG_FUNCTION_ARGS)
+{
+ char *typ_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ Oid typid;
+ int32 typmod;
+ ErrorSaveContext escontext = {T_ErrorSaveContext};
+
+ /* We rely on parseTypeString to parse the input. */
+ if (!parseTypeString(typ_name, &typid, &typmod, (Node *) &escontext))
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT32(typmod);
+}
+
/*
* regtypeout - converts type OID to "typ_name"
*/
{ oid => '3493', descr => 'convert type name to regtype',
proname => 'to_regtype', provolatile => 's', prorettype => 'regtype',
proargtypes => 'text', prosrc => 'to_regtype' },
+{ oid => '8401', descr => 'convert type name to type modifier',
+ proname => 'to_regtypemod', provolatile => 's', prorettype => 'int4',
+ proargtypes => 'text', prosrc => 'to_regtypemod' },
{ oid => '1079', descr => 'convert text to regclass',
proname => 'regclass', provolatile => 's', prorettype => 'regclass',
proargtypes => 'text', prosrc => 'text_regclass' },
(1 row)
+-- Test to_regtypemod
+SELECT to_regtypemod('text');
+ to_regtypemod
+---------------
+ -1
+(1 row)
+
+SELECT to_regtypemod('timestamp(4)');
+ to_regtypemod
+---------------
+ 4
+(1 row)
+
+SELECT to_regtypemod('no_such_type(4)');
+ to_regtypemod
+---------------
+
+(1 row)
+
+SELECT format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)'));
+ format_type
+-----------------------
+ character varying(32)
+(1 row)
+
+SELECT format_type(to_regtype('bit'), to_regtypemod('bit'));
+ format_type
+-------------
+ bit(1)
+(1 row)
+
+SELECT format_type(to_regtype('"bit"'), to_regtypemod('"bit"'));
+ format_type
+-------------
+ "bit"
+(1 row)
+
-- Test soft-error API
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');
message | detail | hint | sql_error_code
SELECT to_regnamespace('"Nonexistent"');
SELECT to_regnamespace('foo.bar');
+-- Test to_regtypemod
+SELECT to_regtypemod('text');
+SELECT to_regtypemod('timestamp(4)');
+SELECT to_regtypemod('no_such_type(4)');
+SELECT format_type(to_regtype('varchar(32)'), to_regtypemod('varchar(32)'));
+SELECT format_type(to_regtype('bit'), to_regtypemod('bit'));
+SELECT format_type(to_regtype('"bit"'), to_regtypemod('"bit"'));
+
-- Test soft-error API
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');