mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add to_regtypemod function to extract typemod from a string type name.
In combination with to_regtype, this allows converting a string to the "canonicalized" form emitted by format_type. That usage requires parsing the string twice, which is slightly annoying but not really too expensive. We considered alternatives such as returning a record type, but that way was notationally uglier than this, and possibly less flexible. Like to_regtype(), we'd rather that this return NULL for any bad input, but the underlying type-parsing logic isn't yet capable of not throwing syntax errors. Adjust the documentation for both functions to point that out. In passing, fix up a couple of nearby entries in the System Catalog Information Functions table that had not gotten the word about our since-v13 convention for displaying function usage examples. David Wheeler and Erik Wienhold, reviewed by Pavel Stehule, Jim Jones, and others. Discussion: https://postgr.es/m/DF2324CA-2673-4ABE-B382-26B5770B6AA3@justatheory.com
This commit is contained in:
@ -24872,7 +24872,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
|
|||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<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>
|
<indexterm>
|
||||||
<primary>format_type</primary>
|
<primary>format_type</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
@ -25387,18 +25387,8 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
|
|||||||
OID for comparison purposes but displays as a type name.
|
OID for comparison purposes but displays as a type name.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
For example:
|
<literal>pg_typeof(33)</literal>
|
||||||
<programlisting>
|
<returnvalue>integer</returnvalue>
|
||||||
SELECT pg_typeof(33);
|
|
||||||
pg_typeof
|
|
||||||
-----------
|
|
||||||
integer
|
|
||||||
|
|
||||||
SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
|
|
||||||
typlen
|
|
||||||
--------
|
|
||||||
4
|
|
||||||
</programlisting>
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -25418,18 +25408,12 @@ SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
|
|||||||
collatable data type, then an error is raised.
|
collatable data type, then an error is raised.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
For example:
|
<literal>collation for ('foo'::text)</literal>
|
||||||
<programlisting>
|
<returnvalue>"default"</returnvalue>
|
||||||
SELECT collation for (description) FROM pg_description LIMIT 1;
|
</para>
|
||||||
pg_collation_for
|
<para>
|
||||||
------------------
|
<literal>collation for ('foo' COLLATE "de_DE")</literal>
|
||||||
"default"
|
<returnvalue>"de_DE"</returnvalue>
|
||||||
|
|
||||||
SELECT collation for ('foo' COLLATE "de_DE");
|
|
||||||
pg_collation_for
|
|
||||||
------------------
|
|
||||||
"de_DE"
|
|
||||||
</programlisting>
|
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
@ -25570,7 +25554,7 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
|||||||
</row>
|
</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>
|
<indexterm>
|
||||||
<primary>to_regtype</primary>
|
<primary>to_regtype</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
@ -25578,11 +25562,42 @@ SELECT collation for ('foo' COLLATE "de_DE");
|
|||||||
<returnvalue>regtype</returnvalue>
|
<returnvalue>regtype</returnvalue>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Translates a textual type name to its OID. A similar result is
|
Parses a string of text, extracts a potential type name from it,
|
||||||
obtained by casting the string to type <type>regtype</type> (see
|
and translates that name into a type OID. A syntax error in the
|
||||||
<xref linkend="datatype-oid"/>); however, this function will return
|
string will result in an error; but if the string is a
|
||||||
<literal>NULL</literal> rather than throwing an error if the name is
|
syntactically valid type name that happens not to be found in the
|
||||||
not found.
|
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>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -1220,6 +1220,26 @@ to_regtype(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_DATUM(result);
|
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"
|
* regtypeout - converts type OID to "typ_name"
|
||||||
*/
|
*/
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202403201
|
#define CATALOG_VERSION_NO 202403202
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7155,6 +7155,9 @@
|
|||||||
{ oid => '3493', descr => 'convert type name to regtype',
|
{ oid => '3493', descr => 'convert type name to regtype',
|
||||||
proname => 'to_regtype', provolatile => 's', prorettype => 'regtype',
|
proname => 'to_regtype', provolatile => 's', prorettype => 'regtype',
|
||||||
proargtypes => 'text', prosrc => 'to_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',
|
{ oid => '1079', descr => 'convert text to regclass',
|
||||||
proname => 'regclass', provolatile => 's', prorettype => 'regclass',
|
proname => 'regclass', provolatile => 's', prorettype => 'regclass',
|
||||||
proargtypes => 'text', prosrc => 'text_regclass' },
|
proargtypes => 'text', prosrc => 'text_regclass' },
|
||||||
|
@ -447,6 +447,43 @@ SELECT to_regnamespace('foo.bar');
|
|||||||
|
|
||||||
(1 row)
|
(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
|
-- Test soft-error API
|
||||||
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');
|
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');
|
||||||
message | detail | hint | sql_error_code
|
message | detail | hint | sql_error_code
|
||||||
|
@ -123,6 +123,14 @@ SELECT to_regnamespace('Nonexistent');
|
|||||||
SELECT to_regnamespace('"Nonexistent"');
|
SELECT to_regnamespace('"Nonexistent"');
|
||||||
SELECT to_regnamespace('foo.bar');
|
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
|
-- Test soft-error API
|
||||||
|
|
||||||
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');
|
SELECT * FROM pg_input_error_info('ng_catalog.pg_class', 'regclass');
|
||||||
|
Reference in New Issue
Block a user