Allow I/O conversion casts to be applied to or from any type that is a member
of the STRING type category, thereby opening up the mechanism for user-defined types. This is mainly for the benefit of citext, though; there aren't likely to be a lot of types that are all general-purpose character strings. Per discussion with David Wheeler.
This commit is contained in:
parent
7df49cef72
commit
c8572986ad
@ -1141,13 +1141,16 @@ SELECT like_escape( name::text, ''::citext ) =like_escape( name::text, '' ) AS t
|
|||||||
t
|
t
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
--- TODO: Get citext working with magic cast functions?
|
--- citext should work as source or destination of I/O conversion casts
|
||||||
SELECT cidr( '192.168.1.2'::citext ) = cidr( '192.168.1.2'::text ) AS "t TODO";
|
SELECT cidr( '192.168.1.2'::citext ) = cidr( '192.168.1.2'::text ) AS "t";
|
||||||
ERROR: function cidr(citext) does not exist
|
t
|
||||||
LINE 1: SELECT cidr( '192.168.1.2'::citext ) = cidr( '192.168.1.2'::...
|
---
|
||||||
^
|
t
|
||||||
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
|
(1 row)
|
||||||
SELECT '192.168.1.2'::cidr::citext = '192.168.1.2'::cidr::text AS "t TODO";
|
|
||||||
ERROR: cannot cast type cidr to citext
|
SELECT '192.168.1.2'::cidr::citext = '192.168.1.2'::cidr::text AS "t";
|
||||||
LINE 1: SELECT '192.168.1.2'::cidr::citext = '192.168.1.2'::cidr::te...
|
t
|
||||||
^
|
---
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
@ -323,6 +323,6 @@ SELECT COUNT(*) = 19::bigint AS t FROM try;
|
|||||||
SELECT like_escape( name, '' ) = like_escape( name::text, '' ) AS t FROM srt;
|
SELECT like_escape( name, '' ) = like_escape( name::text, '' ) AS t FROM srt;
|
||||||
SELECT like_escape( name::text, ''::citext ) =like_escape( name::text, '' ) AS t FROM srt;
|
SELECT like_escape( name::text, ''::citext ) =like_escape( name::text, '' ) AS t FROM srt;
|
||||||
|
|
||||||
--- TODO: Get citext working with magic cast functions?
|
--- citext should work as source or destination of I/O conversion casts
|
||||||
SELECT cidr( '192.168.1.2'::citext ) = cidr( '192.168.1.2'::text ) AS "t TODO";
|
SELECT cidr( '192.168.1.2'::citext ) = cidr( '192.168.1.2'::text ) AS "t";
|
||||||
SELECT '192.168.1.2'::cidr::citext = '192.168.1.2'::cidr::text AS "t TODO";
|
SELECT '192.168.1.2'::cidr::citext = '192.168.1.2'::cidr::text AS "t";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.28 2008/07/12 16:20:06 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.29 2008/07/30 21:23:17 tgl Exp $ -->
|
||||||
|
|
||||||
<refentry id="SQL-CREATECAST">
|
<refentry id="SQL-CREATECAST">
|
||||||
<refmeta>
|
<refmeta>
|
||||||
@ -26,7 +26,7 @@ CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</r
|
|||||||
[ AS ASSIGNMENT | AS IMPLICIT ]
|
[ AS ASSIGNMENT | AS IMPLICIT ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
<refsect1 id="sql-createcast-description">
|
<refsect1 id="sql-createcast-description">
|
||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
@ -131,6 +131,18 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
to <type>int4</>, are best made explicit-only.
|
to <type>int4</>, are best made explicit-only.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
Sometimes it is necessary for usability or standards-compliance reasons
|
||||||
|
to provide multiple implicit casts among a set of types, resulting in
|
||||||
|
ambiguity that cannot be avoided as above. The parser has a fallback
|
||||||
|
heuristic based on <firstterm>type categories</> and <firstterm>preferred
|
||||||
|
types</> that can help to provide desired behavior in such cases. See
|
||||||
|
<xref linkend="sql-createtype" endterm="sql-createtype-title"> for
|
||||||
|
more information.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To be able to create a cast, you must own the source or the target
|
To be able to create a cast, you must own the source or the target
|
||||||
data type. To create a binary-coercible cast, you must be superuser.
|
data type. To create a binary-coercible cast, you must be superuser.
|
||||||
@ -181,8 +193,8 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Indicates that the source type and the target type are binary
|
Indicates that the source type is binary-coercible to the target type,
|
||||||
coercible, so no function is required to perform the cast.
|
so no function is required to perform the cast.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -218,7 +230,7 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
if there is none. The third argument,
|
if there is none. The third argument,
|
||||||
if present, must be type <type>boolean</>; it receives <literal>true</>
|
if present, must be type <type>boolean</>; it receives <literal>true</>
|
||||||
if the cast is an explicit cast, <literal>false</> otherwise.
|
if the cast is an explicit cast, <literal>false</> otherwise.
|
||||||
(Bizarrely, the SQL spec demands different behaviors for explicit and
|
(Bizarrely, the SQL standard demands different behaviors for explicit and
|
||||||
implicit casts in some cases. This argument is supplied for functions
|
implicit casts in some cases. This argument is supplied for functions
|
||||||
that must implement such casts. It is not recommended that you design
|
that must implement such casts. It is not recommended that you design
|
||||||
your own data types so that this matters.)
|
your own data types so that this matters.)
|
||||||
@ -271,7 +283,8 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
<para>
|
<para>
|
||||||
It is normally not necessary to create casts between user-defined types
|
It is normally not necessary to create casts between user-defined types
|
||||||
and the standard string types (<type>text</>, <type>varchar</>, and
|
and the standard string types (<type>text</>, <type>varchar</>, and
|
||||||
<type>char(<replaceable>n</>)</type>). <productname>PostgreSQL</> will
|
<type>char(<replaceable>n</>)</type>, as well as user-defined types that
|
||||||
|
are defined to be in the string category). <productname>PostgreSQL</> will
|
||||||
automatically handle a cast to a string type by invoking the other
|
automatically handle a cast to a string type by invoking the other
|
||||||
type's output function, or conversely handle a cast from a string type
|
type's output function, or conversely handle a cast from a string type
|
||||||
by invoking the other type's input function. These
|
by invoking the other type's input function. These
|
||||||
@ -340,16 +353,15 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To create a cast from type <type>bigint</type> to type
|
To create an assignment cast from type <type>bigint</type> to type
|
||||||
<type>int4</type> using the function <literal>int4(bigint)</literal>:
|
<type>int4</type> using the function <literal>int4(bigint)</literal>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint);
|
CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
(This cast is already predefined in the system.)
|
(This cast is already predefined in the system.)
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
<refsect1 id="sql-createcast-compat">
|
<refsect1 id="sql-createcast-compat">
|
||||||
<title>Compatibility</title>
|
<title>Compatibility</title>
|
||||||
|
|
||||||
@ -358,7 +370,7 @@ CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint);
|
|||||||
<acronym>SQL</acronym> standard,
|
<acronym>SQL</acronym> standard,
|
||||||
except that SQL does not make provisions for binary-coercible
|
except that SQL does not make provisions for binary-coercible
|
||||||
types or extra arguments to implementation functions.
|
types or extra arguments to implementation functions.
|
||||||
<literal>AS IMPLICIT</> is a <productname>PostgreSQL</productname>
|
<literal>AS IMPLICIT</> is a <productname>PostgreSQL</productname>
|
||||||
extension, too.
|
extension, too.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.162 2008/07/30 17:05:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.163 2008/07/30 21:23:17 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1796,8 +1796,8 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we still haven't found a possibility, consider automatic casting
|
* If we still haven't found a possibility, consider automatic casting
|
||||||
* using I/O functions. We allow assignment casts to textual types
|
* using I/O functions. We allow assignment casts to string types
|
||||||
* and explicit casts from textual types to be handled this way. (The
|
* and explicit casts from string types to be handled this way. (The
|
||||||
* CoerceViaIO mechanism is a lot more general than that, but this is
|
* CoerceViaIO mechanism is a lot more general than that, but this is
|
||||||
* all we want to allow in the absence of a pg_cast entry.) It would
|
* all we want to allow in the absence of a pg_cast entry.) It would
|
||||||
* probably be better to insist on explicit casts in both directions,
|
* probably be better to insist on explicit casts in both directions,
|
||||||
@ -1807,14 +1807,10 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
|
|||||||
if (result == COERCION_PATH_NONE)
|
if (result == COERCION_PATH_NONE)
|
||||||
{
|
{
|
||||||
if (ccontext >= COERCION_ASSIGNMENT &&
|
if (ccontext >= COERCION_ASSIGNMENT &&
|
||||||
(targetTypeId == TEXTOID ||
|
TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
|
||||||
targetTypeId == VARCHAROID ||
|
|
||||||
targetTypeId == BPCHAROID))
|
|
||||||
result = COERCION_PATH_COERCEVIAIO;
|
result = COERCION_PATH_COERCEVIAIO;
|
||||||
else if (ccontext >= COERCION_EXPLICIT &&
|
else if (ccontext >= COERCION_EXPLICIT &&
|
||||||
(sourceTypeId == TEXTOID ||
|
TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
|
||||||
sourceTypeId == VARCHAROID ||
|
|
||||||
sourceTypeId == BPCHAROID))
|
|
||||||
result = COERCION_PATH_COERCEVIAIO;
|
result = COERCION_PATH_COERCEVIAIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user