]> granicus.if.org Git - postgresql/commitdiff
Add support for user-defined I/O conversion casts.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 31 Oct 2008 08:39:22 +0000 (08:39 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 31 Oct 2008 08:39:22 +0000 (08:39 +0000)
14 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/create_cast.sgml
src/backend/commands/functioncmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_coerce.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/include/catalog/catversion.h
src/include/catalog/pg_cast.h
src/include/nodes/parsenodes.h
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/opr_sanity.sql

index a68799334add93bb962b4d47d106f6871606ee0e..faee42ba1036d6e6faeec720946ce523ce6570f7 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.179 2008/10/17 22:10:29 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.180 2008/10/31 08:39:19 heikki Exp $ -->
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
  -->
    cannot be deduced from some generic rule.  For example, casting between a
    domain and its base type is not explicitly represented in
    <structname>pg_cast</structname>.  Another important exception is that
-   <quote>I/O conversion casts</>, those performed using a data type's own
-   I/O functions to convert to or from <type>text</> or other string types,
-   are not explicitly represented in <structname>pg_cast</structname>.
+   <quote>automatic I/O conversion casts</>, those performed using a data
+   type's own I/O functions to convert to or from <type>text</> or other
+   string types, are not explicitly represented in
+   <structname>pg_cast</structname>.
   </para>
 
   <table>
       <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
       <entry>
        The OID of the function to use to perform this cast.  Zero is
-       stored if the data types are binary coercible (that is, no
-       run-time operation is needed to perform the cast)
+       stored if the cast method doesn't require a function.
       </entry>
      </row>
 
        other cases
       </entry>
      </row>
+     <row>
+      <entry><structfield>castmethod</structfield></entry>
+      <entry><type>char</type></entry>
+      <entry></entry>
+      <entry>
+       Indicates how the cast is performed.
+       <literal>f</> means that the function specified in the <structfield>castfunc</> field is used.
+       <literal>i</> means that the input/output functions are used.
+       <literal>b</> means that the types are binary-coercible, thus no conversion is required
+      </entry>
+     </row>
     </tbody>
    </tgroup>
   </table>
index 080f31832d2e92d9d1cfbd731565dae95f7146b4..c771d22ad9480ef50cec04d8e489ad27dea894a3 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.29 2008/07/30 21:23:17 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/ref/create_cast.sgml,v 1.30 2008/10/31 08:39:20 heikki Exp $ -->
 
 <refentry id="SQL-CREATECAST">
  <refmeta>
@@ -24,6 +24,10 @@ CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</r
 CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
     WITHOUT FUNCTION
     [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (<replaceable>sourcetype</replaceable> AS <replaceable>targettype</replaceable>)
+    WITH INOUT
+    [ AS ASSIGNMENT | AS IMPLICIT ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -58,6 +62,13 @@ SELECT CAST(42 AS float8);
    binary compatible.)
   </para>
 
+  <para>
+   You can define a cast as an <firstterm>I/O conversion cast</> using
+   the <literal>WITH INOUT</literal> syntax. An I/O conversion cast is
+   performed by invoking the output function of the source data type, and
+   passing the result to the input function of the target data type.
+  </para>
+
   <para>
    By default, a cast can be invoked only by an explicit cast request,
    that is an explicit <literal>CAST(<replaceable>x</> AS
@@ -199,6 +210,18 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
      </listitem>
     </varlistentry>
 
+    <varlistentry>
+     <term><literal>WITH INOUT</literal></term>
+
+     <listitem>
+      <para>
+       Indicates that the cast is an I/O conversion cast, performed by
+       invoking the output function of the source data type, and passing the
+       result to the input function of the target data type.
+      </para>
+     </listitem>
+    </varlistentry>
+
     <varlistentry>
      <term><literal>AS ASSIGNMENT</literal></term>
 
@@ -284,15 +307,12 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
    It is normally not necessary to create casts between user-defined types
    and the standard string types (<type>text</>, <type>varchar</>, and
    <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
-   type's output function, or conversely handle a cast from a string type
-   by invoking the other type's input function.  These
-   automatically-provided casts are known as <firstterm>I/O conversion
-   casts</>.  I/O conversion casts to string types are treated as
-   assignment casts, while I/O conversion casts from string types are
+   are defined to be in the string category).  <productname>PostgreSQL</>
+   provides automatic I/O conversion casts for that. The automatic casts to
+   string types are treated as assignment casts, while the automatic casts
+   from string types are
    explicit-only.  You can override this behavior by declaring your own
-   cast to replace an I/O conversion cast, but usually the only reason to
+   cast to replace an automatic cast, but usually the only reason to
    do so is if you want the conversion to be more easily invokable than the
    standard assignment-only or explicit-only setting.  Another possible
    reason is that you want the conversion to behave differently from the
index 12762b8aaabf56d9a9010904effaedbe462e9ada..80a57457ee506065824d278dbec918280b704c0c 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.99 2008/10/21 10:38:51 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.100 2008/10/31 08:39:20 heikki Exp $
  *
  * DESCRIPTION
  *       These routines take the parse tree and pick out the
@@ -1383,6 +1383,7 @@ CreateCast(CreateCastStmt *stmt)
        Oid                     funcid;
        int                     nargs;
        char            castcontext;
+       char            castmethod;
        Relation        relation;
        HeapTuple       tuple;
        Datum           values[Natts_pg_cast];
@@ -1415,7 +1416,15 @@ CreateCast(CreateCastStmt *stmt)
                                                format_type_be(sourcetypeid),
                                                format_type_be(targettypeid))));
 
+       /* Detemine the cast method */
        if (stmt->func != NULL)
+               castmethod = COERCION_METHOD_FUNCTION;
+       else if(stmt->inout)
+               castmethod = COERCION_METHOD_INOUT;
+       else
+               castmethod = COERCION_METHOD_BINARY;
+
+       if (castmethod == COERCION_METHOD_FUNCTION)
        {
                Form_pg_proc procstruct;
 
@@ -1475,6 +1484,12 @@ CreateCast(CreateCastStmt *stmt)
                ReleaseSysCache(tuple);
        }
        else
+       {
+               funcid = InvalidOid;
+               nargs = 0;
+       }
+
+       if (castmethod == COERCION_METHOD_BINARY)
        {
                int16           typ1len;
                int16           typ2len;
@@ -1483,10 +1498,6 @@ CreateCast(CreateCastStmt *stmt)
                char            typ1align;
                char            typ2align;
 
-               /* indicates binary coercibility */
-               funcid = InvalidOid;
-               nargs = 0;
-
                /*
                 * Must be superuser to create binary-compatible casts, since
                 * erroneous casts can easily crash the backend.
@@ -1562,6 +1573,7 @@ CreateCast(CreateCastStmt *stmt)
        values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
        values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
        values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
+       values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
 
        MemSet(nulls, ' ', Natts_pg_cast);
 
index 2dce7bab18f28507d275154f829f2c9052e13d1a..d56075e6bbfab7090eebae52d1deb67214f03fcf 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.409 2008/10/21 20:42:52 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.410 2008/10/31 08:39:20 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3042,6 +3042,7 @@ _copyCreateCastStmt(CreateCastStmt *from)
        COPY_NODE_FIELD(targettype);
        COPY_NODE_FIELD(func);
        COPY_SCALAR_FIELD(context);
+       COPY_SCALAR_FIELD(inout);
 
        return newnode;
 }
index e0b8bdcecb1230ad8e75ca870ef10a5df6d1d10f..e17aff89228ce805856bb9784b9514619d79f502 100644 (file)
@@ -22,7 +22,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.334 2008/10/21 20:42:52 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.335 2008/10/31 08:39:20 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1666,6 +1666,7 @@ _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
        COMPARE_NODE_FIELD(targettype);
        COMPARE_NODE_FIELD(func);
        COMPARE_SCALAR_FIELD(context);
+       COMPARE_SCALAR_FIELD(inout);
 
        return true;
 }
index 8b44e5b6ba4aebdd53b5b371a0aaf597585d9454..b78d5b302e38973471ae8f08689b58be094a4bf1 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.632 2008/10/29 11:24:53 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.633 2008/10/31 08:39:20 heikki Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -4590,6 +4590,7 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
                                        n->targettype = $6;
                                        n->func = $10;
                                        n->context = (CoercionContext) $11;
+                                       n->inout = false;
                                        $$ = (Node *)n;
                                }
                        | CREATE CAST '(' Typename AS Typename ')'
@@ -4600,6 +4601,18 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
                                        n->targettype = $6;
                                        n->func = NULL;
                                        n->context = (CoercionContext) $10;
+                                       n->inout = false;
+                                       $$ = (Node *)n;
+                               }
+                       | CREATE CAST '(' Typename AS Typename ')'
+                                       WITH INOUT cast_context
+                               {
+                                       CreateCastStmt *n = makeNode(CreateCastStmt);
+                                       n->sourcetype = $4;
+                                       n->targettype = $6;
+                                       n->func = NULL;
+                                       n->context = (CoercionContext) $10;
+                                       n->inout = true;
                                        $$ = (Node *)n;
                                }
                ;
index 6d703ae571884d9c5cba8252e99020ed7e5fd0a0..112a07beb581e5aed663924a22f1a48d5249a3f6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.170 2008/10/25 17:19:09 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.171 2008/10/31 08:39:21 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1909,11 +1909,23 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId,
                /* Rely on ordering of enum for correct behavior here */
                if (ccontext >= castcontext)
                {
-                       *funcid = castForm->castfunc;
-                       if (OidIsValid(*funcid))
-                               result = COERCION_PATH_FUNC;
-                       else
-                               result = COERCION_PATH_RELABELTYPE;
+                       switch (castForm->castmethod)
+                       {
+                               case COERCION_METHOD_FUNCTION:
+                                       result = COERCION_PATH_FUNC;
+                                       *funcid = castForm->castfunc;
+                                       break;
+                               case COERCION_METHOD_INOUT:
+                                       result = COERCION_PATH_COERCEVIAIO;
+                                       break;
+                               case COERCION_METHOD_BINARY:
+                                       result = COERCION_PATH_RELABELTYPE;
+                                       break;
+                               default:
+                                       elog(ERROR, "unrecognized castmethod: %d",
+                                                (int) castForm->castmethod);
+                                       break;
+                       }
                }
 
                ReleaseSysCache(tuple);
index 074b647c338c43f07b9f75b927aac49e1d4096cd..ac05a4a5b70f2ec9ed7bd1aceb02abe7ffe1f3ff 100644 (file)
@@ -12,7 +12,7 @@
  *     by PostgreSQL
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.502 2008/09/24 19:33:15 heikki Exp $
+ *       $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.503 2008/10/31 08:39:21 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,6 +36,7 @@ int                   optreset;
 
 #include "access/attnum.h"
 #include "access/sysattr.h"
+#include "catalog/pg_cast.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_trigger.h"
@@ -4410,21 +4411,31 @@ getCasts(int *numCasts)
        int                     i_casttarget;
        int                     i_castfunc;
        int                     i_castcontext;
+       int                     i_castmethod;
 
        /* Make sure we are in proper schema */
        selectSourceSchema("pg_catalog");
 
-       if (g_fout->remoteVersion >= 70300)
+       if (g_fout->remoteVersion >= 80400)
+       {
+               appendPQExpBuffer(query, "SELECT tableoid, oid, "
+                                                 "castsource, casttarget, castfunc, castcontext, "
+                                                 "castmethod "
+                                                 "FROM pg_cast ORDER BY 3,4");
+       }
+       else if (g_fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, "
-                                                 "castsource, casttarget, castfunc, castcontext "
+                                                 "castsource, casttarget, castfunc, castcontext, "
+                                                 "CASE WHEN castfunc = 0 THEN 'b' ELSE 'f' END AS castmethod "
                                                  "FROM pg_cast ORDER BY 3,4");
        }
        else
        {
                appendPQExpBuffer(query, "SELECT 0 as tableoid, p.oid, "
                                                  "t1.oid as castsource, t2.oid as casttarget, "
-                                                 "p.oid as castfunc, 'e' as castcontext "
+                                                 "p.oid as castfunc, 'e' as castcontext, "
+                                                 "'f' as castmethod "
                                                  "FROM pg_type t1, pg_type t2, pg_proc p "
                                                  "WHERE p.pronargs = 1 AND "
                                                  "p.proargtypes[0] = t1.oid AND "
@@ -4447,6 +4458,7 @@ getCasts(int *numCasts)
        i_casttarget = PQfnumber(res, "casttarget");
        i_castfunc = PQfnumber(res, "castfunc");
        i_castcontext = PQfnumber(res, "castcontext");
+       i_castmethod = PQfnumber(res, "castmethod");
 
        for (i = 0; i < ntups; i++)
        {
@@ -4462,6 +4474,7 @@ getCasts(int *numCasts)
                castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
                castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
                castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
+               castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
 
                /*
                 * Try to name cast as concatenation of typnames.  This is only used
@@ -7188,18 +7201,26 @@ dumpCast(Archive *fout, CastInfo *cast)
                                          getFormattedTypeName(cast->castsource, zeroAsNone),
                                          getFormattedTypeName(cast->casttarget, zeroAsNone));
 
-       if (!OidIsValid(cast->castfunc))
-               appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
-       else
+       switch(cast->castmethod)
        {
-               /*
-                * Always qualify the function name, in case it is not in pg_catalog
-                * schema (format_function_signature won't qualify it).
-                */
-               appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
-                                                 fmtId(funcInfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(defqry, "%s",
-                                                 format_function_signature(funcInfo, true));
+               case COERCION_METHOD_BINARY:
+                       appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
+                       break;
+               case COERCION_METHOD_INOUT:
+                       appendPQExpBuffer(defqry, "WITH INOUT");
+                       break;
+               case COERCION_METHOD_FUNCTION:
+                       /*
+                        * Always qualify the function name, in case it is not in
+                        * pg_catalog schema (format_function_signature won't qualify it).
+                        */
+                       appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
+                                                         fmtId(funcInfo->dobj.namespace->dobj.name));
+                       appendPQExpBuffer(defqry, "%s",
+                                                         format_function_signature(funcInfo, true));
+                       break;
+               default:
+                       write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
        }
 
        if (cast->castcontext == 'a')
index f443d9de590bffab4321bef37a82143225e3d50d..80f02efb2f12338dd205cea99a7bd1f02acbdef3 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.141 2008/09/08 15:26:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.142 2008/10/31 08:39:21 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -376,6 +376,7 @@ typedef struct _castInfo
        Oid                     casttarget;
        Oid                     castfunc;
        char            castcontext;
+       char            castmethod;
 } CastInfo;
 
 /* InhInfo isn't a DumpableObject, just temporary state */
index f242dcf469e813ca32897b9e335e734971beba01..3d0db7a461d172b6d4eae4218cb29355d2bd7e1d 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.499 2008/10/17 22:10:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.500 2008/10/31 08:39:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200810171
+#define CATALOG_VERSION_NO     200810311
 
 #endif
index 5ad101361c93410d55dcec1447d2960a59a98fe5..466815575fea0ae50f17f6a305ffffa23b60211d 100644 (file)
@@ -10,7 +10,7 @@
  *
  * Copyright (c) 2002-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.39 2008/03/27 03:57:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.40 2008/10/31 08:39:22 heikki Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -36,6 +36,7 @@ CATALOG(pg_cast,2605)
        Oid                     casttarget;             /* destination datatype for cast */
        Oid                     castfunc;               /* cast function; 0 = binary coercible */
        char            castcontext;    /* contexts in which cast can be used */
+       char            castmethod;             /* cast method */
 } FormData_pg_cast;
 
 typedef FormData_pg_cast *Form_pg_cast;
@@ -56,16 +57,29 @@ typedef enum CoercionCodes
        COERCION_CODE_EXPLICIT = 'e'    /* explicit cast operation */
 } CoercionCodes;
 
+/*
+ * The allowable values for pg_cast.castmethod are specified by this enum.
+ * Since castcontext is stored as a "char", we use ASCII codes for human
+ * convenience in reading the table.
+ */
+typedef enum CoercionMethod
+{
+       COERCION_METHOD_FUNCTION = 'f',         /* use a function */
+       COERCION_METHOD_BINARY = 'b',           /* types are binary-compatible */
+       COERCION_METHOD_INOUT = 'i'                     /* use input/output functions */
+} CoercionMethod;
+
 
 /* ----------------
  *             compiler constants for pg_cast
  * ----------------
  */
-#define Natts_pg_cast                          4
+#define Natts_pg_cast                          5
 #define Anum_pg_cast_castsource                1
 #define Anum_pg_cast_casttarget                2
 #define Anum_pg_cast_castfunc          3
 #define Anum_pg_cast_castcontext       4
+#define Anum_pg_cast_castmethod                5
 
 /* ----------------
  *             initial contents of pg_cast
@@ -80,40 +94,40 @@ typedef enum CoercionCodes
  * int2->int4->int8->numeric->float4->float8, while casts in the
  * reverse direction are assignment-only.
  */
-DATA(insert (  20       21  714 a ));
-DATA(insert (  20       23  480 a ));
-DATA(insert (  20      700  652 i ));
-DATA(insert (  20      701  482 i ));
-DATA(insert (  20 1700 1781 i ));
-DATA(insert (  21       20  754 i ));
-DATA(insert (  21       23  313 i ));
-DATA(insert (  21      700  236 i ));
-DATA(insert (  21      701  235 i ));
-DATA(insert (  21 1700 1782 i ));
-DATA(insert (  23       20  481 i ));
-DATA(insert (  23       21  314 a ));
-DATA(insert (  23      700  318 i ));
-DATA(insert (  23      701  316 i ));
-DATA(insert (  23 1700 1740 i ));
-DATA(insert (  700      20  653 a ));
-DATA(insert (  700      21  238 a ));
-DATA(insert (  700      23  319 a ));
-DATA(insert (  700     701  311 i ));
-DATA(insert (  700 1700 1742 a ));
-DATA(insert (  701      20  483 a ));
-DATA(insert (  701      21  237 a ));
-DATA(insert (  701      23  317 a ));
-DATA(insert (  701     700  312 a ));
-DATA(insert (  701 1700 1743 a ));
-DATA(insert ( 1700      20 1779 a ));
-DATA(insert ( 1700      21 1783 a ));
-DATA(insert ( 1700      23 1744 a ));
-DATA(insert ( 1700     700 1745 i ));
-DATA(insert ( 1700     701 1746 i ));
+DATA(insert (  20       21  714 a ));
+DATA(insert (  20       23  480 a ));
+DATA(insert (  20      700  652 i ));
+DATA(insert (  20      701  482 i ));
+DATA(insert (  20 1700 1781 i ));
+DATA(insert (  21       20  754 i ));
+DATA(insert (  21       23  313 i ));
+DATA(insert (  21      700  236 i ));
+DATA(insert (  21      701  235 i ));
+DATA(insert (  21 1700 1782 i ));
+DATA(insert (  23       20  481 i ));
+DATA(insert (  23       21  314 a ));
+DATA(insert (  23      700  318 i ));
+DATA(insert (  23      701  316 i ));
+DATA(insert (  23 1700 1740 i ));
+DATA(insert (  700      20  653 a ));
+DATA(insert (  700      21  238 a ));
+DATA(insert (  700      23  319 a ));
+DATA(insert (  700     701  311 i ));
+DATA(insert (  700 1700 1742 a ));
+DATA(insert (  701      20  483 a ));
+DATA(insert (  701      21  237 a ));
+DATA(insert (  701      23  317 a ));
+DATA(insert (  701     700  312 a ));
+DATA(insert (  701 1700 1743 a ));
+DATA(insert ( 1700      20 1779 a ));
+DATA(insert ( 1700      21 1783 a ));
+DATA(insert ( 1700      23 1744 a ));
+DATA(insert ( 1700     700 1745 i ));
+DATA(insert ( 1700     701 1746 i ));
 
 /* Allow explicit coercions between int4 and bool */
-DATA(insert (  23      16      2557 e ));
-DATA(insert (  16      23      2558 e ));
+DATA(insert (  23      16      2557 e ));
+DATA(insert (  16      23      2558 e ));
 
 /*
  * OID category: allow implicit conversion from any integral type (including
@@ -125,164 +139,164 @@ DATA(insert (   16      23      2558 e ));
  * casts from text and varchar to regclass, which exist mainly to support
  * legacy forms of nextval() and related functions.
  */
-DATA(insert (  20       26 1287 i ));
-DATA(insert (  21       26  313 i ));
-DATA(insert (  23       26    0 i ));
-DATA(insert (  26       20 1288 a ));
-DATA(insert (  26       23    0 a ));
-DATA(insert (  26       24    0 i ));
-DATA(insert (  24       26    0 i ));
-DATA(insert (  20       24 1287 i ));
-DATA(insert (  21       24  313 i ));
-DATA(insert (  23       24    0 i ));
-DATA(insert (  24       20 1288 a ));
-DATA(insert (  24       23    0 a ));
-DATA(insert (  24 2202    0 i ));
-DATA(insert ( 2202      24    0 i ));
-DATA(insert (  26 2202    0 i ));
-DATA(insert ( 2202      26    0 i ));
-DATA(insert (  20 2202 1287 i ));
-DATA(insert (  21 2202  313 i ));
-DATA(insert (  23 2202    0 i ));
-DATA(insert ( 2202      20 1288 a ));
-DATA(insert ( 2202      23    0 a ));
-DATA(insert (  26 2203    0 i ));
-DATA(insert ( 2203      26    0 i ));
-DATA(insert (  20 2203 1287 i ));
-DATA(insert (  21 2203  313 i ));
-DATA(insert (  23 2203    0 i ));
-DATA(insert ( 2203      20 1288 a ));
-DATA(insert ( 2203      23    0 a ));
-DATA(insert ( 2203 2204    0 i ));
-DATA(insert ( 2204 2203    0 i ));
-DATA(insert (  26 2204    0 i ));
-DATA(insert ( 2204      26    0 i ));
-DATA(insert (  20 2204 1287 i ));
-DATA(insert (  21 2204  313 i ));
-DATA(insert (  23 2204    0 i ));
-DATA(insert ( 2204      20 1288 a ));
-DATA(insert ( 2204      23    0 a ));
-DATA(insert (  26 2205    0 i ));
-DATA(insert ( 2205      26    0 i ));
-DATA(insert (  20 2205 1287 i ));
-DATA(insert (  21 2205  313 i ));
-DATA(insert (  23 2205    0 i ));
-DATA(insert ( 2205      20 1288 a ));
-DATA(insert ( 2205      23    0 a ));
-DATA(insert (  26 2206    0 i ));
-DATA(insert ( 2206      26    0 i ));
-DATA(insert (  20 2206 1287 i ));
-DATA(insert (  21 2206  313 i ));
-DATA(insert (  23 2206    0 i ));
-DATA(insert ( 2206      20 1288 a ));
-DATA(insert ( 2206      23    0 a ));
-DATA(insert (  26 3734    0 i ));
-DATA(insert ( 3734      26    0 i ));
-DATA(insert (  20 3734 1287 i ));
-DATA(insert (  21 3734  313 i ));
-DATA(insert (  23 3734    0 i ));
-DATA(insert ( 3734      20 1288 a ));
-DATA(insert ( 3734      23    0 a ));
-DATA(insert (  26 3769    0 i ));
-DATA(insert ( 3769      26    0 i ));
-DATA(insert (  20 3769 1287 i ));
-DATA(insert (  21 3769  313 i ));
-DATA(insert (  23 3769    0 i ));
-DATA(insert ( 3769      20 1288 a ));
-DATA(insert ( 3769      23    0 a ));
-DATA(insert (  25 2205 1079 i ));
-DATA(insert ( 1043 2205 1079 i ));
+DATA(insert (  20       26 1287 i ));
+DATA(insert (  21       26  313 i ));
+DATA(insert (  23       26    0 i ));
+DATA(insert (  26       20 1288 a ));
+DATA(insert (  26       23    0 a ));
+DATA(insert (  26       24    0 i ));
+DATA(insert (  24       26    0 i ));
+DATA(insert (  20       24 1287 i ));
+DATA(insert (  21       24  313 i ));
+DATA(insert (  23       24    0 i ));
+DATA(insert (  24       20 1288 a ));
+DATA(insert (  24       23    0 a ));
+DATA(insert (  24 2202    0 i ));
+DATA(insert ( 2202      24    0 i ));
+DATA(insert (  26 2202    0 i ));
+DATA(insert ( 2202      26    0 i ));
+DATA(insert (  20 2202 1287 i ));
+DATA(insert (  21 2202  313 i ));
+DATA(insert (  23 2202    0 i ));
+DATA(insert ( 2202      20 1288 a ));
+DATA(insert ( 2202      23    0 a ));
+DATA(insert (  26 2203    0 i ));
+DATA(insert ( 2203      26    0 i ));
+DATA(insert (  20 2203 1287 i ));
+DATA(insert (  21 2203  313 i ));
+DATA(insert (  23 2203    0 i ));
+DATA(insert ( 2203      20 1288 a ));
+DATA(insert ( 2203      23    0 a ));
+DATA(insert ( 2203 2204    0 i ));
+DATA(insert ( 2204 2203    0 i ));
+DATA(insert (  26 2204    0 i ));
+DATA(insert ( 2204      26    0 i ));
+DATA(insert (  20 2204 1287 i ));
+DATA(insert (  21 2204  313 i ));
+DATA(insert (  23 2204    0 i ));
+DATA(insert ( 2204      20 1288 a ));
+DATA(insert ( 2204      23    0 a ));
+DATA(insert (  26 2205    0 i ));
+DATA(insert ( 2205      26    0 i ));
+DATA(insert (  20 2205 1287 i ));
+DATA(insert (  21 2205  313 i ));
+DATA(insert (  23 2205    0 i ));
+DATA(insert ( 2205      20 1288 a ));
+DATA(insert ( 2205      23    0 a ));
+DATA(insert (  26 2206    0 i ));
+DATA(insert ( 2206      26    0 i ));
+DATA(insert (  20 2206 1287 i ));
+DATA(insert (  21 2206  313 i ));
+DATA(insert (  23 2206    0 i ));
+DATA(insert ( 2206      20 1288 a ));
+DATA(insert ( 2206      23    0 a ));
+DATA(insert (  26 3734    0 i ));
+DATA(insert ( 3734      26    0 i ));
+DATA(insert (  20 3734 1287 i ));
+DATA(insert (  21 3734  313 i ));
+DATA(insert (  23 3734    0 i ));
+DATA(insert ( 3734      20 1288 a ));
+DATA(insert ( 3734      23    0 a ));
+DATA(insert (  26 3769    0 i ));
+DATA(insert ( 3769      26    0 i ));
+DATA(insert (  20 3769 1287 i ));
+DATA(insert (  21 3769  313 i ));
+DATA(insert (  23 3769    0 i ));
+DATA(insert ( 3769      20 1288 a ));
+DATA(insert ( 3769      23    0 a ));
+DATA(insert (  25 2205 1079 i ));
+DATA(insert ( 1043 2205 1079 i ));
 
 /*
  * String category
  */
-DATA(insert (  25 1042    0 i ));
-DATA(insert (  25 1043    0 i ));
-DATA(insert ( 1042      25  401 i ));
-DATA(insert ( 1042 1043  401 i ));
-DATA(insert ( 1043      25    0 i ));
-DATA(insert ( 1043 1042    0 i ));
-DATA(insert (  18       25  946 i ));
-DATA(insert (  18 1042  860 a ));
-DATA(insert (  18 1043  946 a ));
-DATA(insert (  19       25  406 i ));
-DATA(insert (  19 1042  408 a ));
-DATA(insert (  19 1043 1401 a ));
-DATA(insert (  25       18  944 a ));
-DATA(insert ( 1042      18  944 a ));
-DATA(insert ( 1043      18  944 a ));
-DATA(insert (  25       19  407 i ));
-DATA(insert ( 1042      19  409 i ));
-DATA(insert ( 1043      19 1400 i ));
+DATA(insert (  25 1042    0 i ));
+DATA(insert (  25 1043    0 i ));
+DATA(insert ( 1042      25  401 i ));
+DATA(insert ( 1042 1043  401 i ));
+DATA(insert ( 1043      25    0 i ));
+DATA(insert ( 1043 1042    0 i ));
+DATA(insert (  18       25  946 i ));
+DATA(insert (  18 1042  860 a ));
+DATA(insert (  18 1043  946 a ));
+DATA(insert (  19       25  406 i ));
+DATA(insert (  19 1042  408 a ));
+DATA(insert (  19 1043 1401 a ));
+DATA(insert (  25       18  944 a ));
+DATA(insert ( 1042      18  944 a ));
+DATA(insert ( 1043      18  944 a ));
+DATA(insert (  25       19  407 i ));
+DATA(insert ( 1042      19  409 i ));
+DATA(insert ( 1043      19 1400 i ));
 
 /* Allow explicit coercions between int4 and "char" */
-DATA(insert (  18       23   77 e ));
-DATA(insert (  23       18   78 e ));
+DATA(insert (  18       23   77 e ));
+DATA(insert (  23       18   78 e ));
 
 /*
  * Datetime category
  */
-DATA(insert (  702 1082 1179 a ));
-DATA(insert (  702 1083 1364 a ));
-DATA(insert (  702 1114 2023 i ));
-DATA(insert (  702 1184 1173 i ));
-DATA(insert (  703 1186 1177 i ));
-DATA(insert ( 1082 1114 2024 i ));
-DATA(insert ( 1082 1184 1174 i ));
-DATA(insert ( 1083 1186 1370 i ));
-DATA(insert ( 1083 1266 2047 i ));
-DATA(insert ( 1114     702 2030 a ));
-DATA(insert ( 1114 1082 2029 a ));
-DATA(insert ( 1114 1083 1316 a ));
-DATA(insert ( 1114 1184 2028 i ));
-DATA(insert ( 1184     702 1180 a ));
-DATA(insert ( 1184 1082 1178 a ));
-DATA(insert ( 1184 1083 2019 a ));
-DATA(insert ( 1184 1114 2027 a ));
-DATA(insert ( 1184 1266 1388 a ));
-DATA(insert ( 1186     703 1194 a ));
-DATA(insert ( 1186 1083 1419 a ));
-DATA(insert ( 1266 1083 2046 a ));
+DATA(insert (  702 1082 1179 a ));
+DATA(insert (  702 1083 1364 a ));
+DATA(insert (  702 1114 2023 i ));
+DATA(insert (  702 1184 1173 i ));
+DATA(insert (  703 1186 1177 i ));
+DATA(insert ( 1082 1114 2024 i ));
+DATA(insert ( 1082 1184 1174 i ));
+DATA(insert ( 1083 1186 1370 i ));
+DATA(insert ( 1083 1266 2047 i ));
+DATA(insert ( 1114     702 2030 a ));
+DATA(insert ( 1114 1082 2029 a ));
+DATA(insert ( 1114 1083 1316 a ));
+DATA(insert ( 1114 1184 2028 i ));
+DATA(insert ( 1184     702 1180 a ));
+DATA(insert ( 1184 1082 1178 a ));
+DATA(insert ( 1184 1083 2019 a ));
+DATA(insert ( 1184 1114 2027 a ));
+DATA(insert ( 1184 1266 1388 a ));
+DATA(insert ( 1186     703 1194 a ));
+DATA(insert ( 1186 1083 1419 a ));
+DATA(insert ( 1266 1083 2046 a ));
 /* Cross-category casts between int4 and abstime, reltime */
-DATA(insert (  23      702    0 e ));
-DATA(insert (  702      23    0 e ));
-DATA(insert (  23      703    0 e ));
-DATA(insert (  703      23    0 e ));
+DATA(insert (  23      702    0 e ));
+DATA(insert (  702      23    0 e ));
+DATA(insert (  23      703    0 e ));
+DATA(insert (  703      23    0 e ));
 
 /*
  * Geometric category
  */
-DATA(insert (  601     600 1532 e ));
-DATA(insert (  602     600 1533 e ));
-DATA(insert (  602     604 1449 a ));
-DATA(insert (  603     600 1534 e ));
-DATA(insert (  603     601 1541 e ));
-DATA(insert (  603     604 1448 a ));
-DATA(insert (  603     718 1479 e ));
-DATA(insert (  604     600 1540 e ));
-DATA(insert (  604     602 1447 a ));
-DATA(insert (  604     603 1446 e ));
-DATA(insert (  604     718 1474 e ));
-DATA(insert (  718     600 1416 e ));
-DATA(insert (  718     603 1480 e ));
-DATA(insert (  718     604 1544 e ));
+DATA(insert (  601     600 1532 e ));
+DATA(insert (  602     600 1533 e ));
+DATA(insert (  602     604 1449 a ));
+DATA(insert (  603     600 1534 e ));
+DATA(insert (  603     601 1541 e ));
+DATA(insert (  603     604 1448 a ));
+DATA(insert (  603     718 1479 e ));
+DATA(insert (  604     600 1540 e ));
+DATA(insert (  604     602 1447 a ));
+DATA(insert (  604     603 1446 e ));
+DATA(insert (  604     718 1474 e ));
+DATA(insert (  718     600 1416 e ));
+DATA(insert (  718     603 1480 e ));
+DATA(insert (  718     604 1544 e ));
 
 /*
  * INET category
  */
-DATA(insert (  650     869    0 i ));
-DATA(insert (  869     650 1715 a ));
+DATA(insert (  650     869    0 i ));
+DATA(insert (  869     650 1715 a ));
 
 /*
  * BitString category
  */
-DATA(insert ( 1560 1562    0 i ));
-DATA(insert ( 1562 1560    0 i ));
+DATA(insert ( 1560 1562    0 i ));
+DATA(insert ( 1562 1560    0 i ));
 /* Cross-category casts between bit and int4, int8 */
-DATA(insert (  20 1560 2075 e ));
-DATA(insert (  23 1560 1683 e ));
-DATA(insert ( 1560      20 2076 e ));
-DATA(insert ( 1560      23 1684 e ));
+DATA(insert (  20 1560 2075 e ));
+DATA(insert (  23 1560 1683 e ));
+DATA(insert ( 1560      20 2076 e ));
+DATA(insert ( 1560      23 1684 e ));
 
 /*
  * Cross-category casts to and from TEXT
@@ -296,46 +310,46 @@ DATA(insert ( 1560         23 1684 e ));
  * behavior will ensue when the automatic cast is applied instead of the
  * pg_cast entry!
  */
-DATA(insert (  650      25  730 a ));
-DATA(insert (  869      25  730 a ));
-DATA(insert (  16       25 2971 a ));
-DATA(insert (  142      25    0 a ));
-DATA(insert (  25      142 2896 e ));
+DATA(insert (  650      25  730 a ));
+DATA(insert (  869      25  730 a ));
+DATA(insert (  16       25 2971 a ));
+DATA(insert (  142      25    0 a ));
+DATA(insert (  25      142 2896 e ));
 
 /*
  * Cross-category casts to and from VARCHAR
  *
  * We support all the same casts as for TEXT.
  */
-DATA(insert (  650 1043  730 a ));
-DATA(insert (  869 1043  730 a ));
-DATA(insert (  16 1043 2971 a ));
-DATA(insert (  142 1043    0 a ));
-DATA(insert ( 1043     142 2896 e ));
+DATA(insert (  650 1043  730 a ));
+DATA(insert (  869 1043  730 a ));
+DATA(insert (  16 1043 2971 a ));
+DATA(insert (  142 1043    0 a ));
+DATA(insert ( 1043     142 2896 e ));
 
 /*
  * Cross-category casts to and from BPCHAR
  *
  * We support all the same casts as for TEXT.
  */
-DATA(insert (  650 1042  730 a ));
-DATA(insert (  869 1042  730 a ));
-DATA(insert (  16 1042 2971 a ));
-DATA(insert (  142 1042    0 a ));
-DATA(insert ( 1042     142 2896 e ));
+DATA(insert (  650 1042  730 a ));
+DATA(insert (  869 1042  730 a ));
+DATA(insert (  16 1042 2971 a ));
+DATA(insert (  142 1042    0 a ));
+DATA(insert ( 1042     142 2896 e ));
 
 /*
  * Length-coercion functions
  */
-DATA(insert ( 1042 1042  668 i ));
-DATA(insert ( 1043 1043  669 i ));
-DATA(insert ( 1083 1083 1968 i ));
-DATA(insert ( 1114 1114 1961 i ));
-DATA(insert ( 1184 1184 1967 i ));
-DATA(insert ( 1186 1186 1200 i ));
-DATA(insert ( 1266 1266 1969 i ));
-DATA(insert ( 1560 1560 1685 i ));
-DATA(insert ( 1562 1562 1687 i ));
-DATA(insert ( 1700 1700 1703 i ));
+DATA(insert ( 1042 1042  668 i ));
+DATA(insert ( 1043 1043  669 i ));
+DATA(insert ( 1083 1083 1968 i ));
+DATA(insert ( 1114 1114 1961 i ));
+DATA(insert ( 1184 1184 1967 i ));
+DATA(insert ( 1186 1186 1200 i ));
+DATA(insert ( 1266 1266 1969 i ));
+DATA(insert ( 1560 1560 1685 i ));
+DATA(insert ( 1562 1562 1687 i ));
+DATA(insert ( 1700 1700 1703 i ));
 
 #endif   /* PG_CAST_H */
index 2660d7adb80c8f2e74e1211ce5b360d3e1da7fbe..5e112d178ba236eae84068341a096a338d4089c3 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.376 2008/10/04 21:56:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.377 2008/10/31 08:39:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2062,6 +2062,7 @@ typedef struct CreateCastStmt
        TypeName   *targettype;
        FuncWithArgs *func;
        CoercionContext context;
+       bool            inout;
 } CreateCastStmt;
 
 /* ----------------------
index a21c2ba3744250a84dbc4a175dcf8d095b979125..87464ec9cf4557a717f83e0d716afa5734cdfdff 100644 (file)
@@ -22,7 +22,7 @@ create function binary_coercible(oid, oid) returns bool as $$
 SELECT ($1 = $2) OR
  EXISTS(select 1 from pg_catalog.pg_cast where
         castsource = $1 and casttarget = $2 and
-        castfunc = 0 and castcontext = 'i') OR
+        castmethod = 'b' and castcontext = 'i') OR
  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
   EXISTS(select 1 from pg_catalog.pg_type where
          oid = $1 and typelem != 0 and typlen = -1))
@@ -33,7 +33,7 @@ create function physically_coercible(oid, oid) returns bool as $$
 SELECT ($1 = $2) OR
  EXISTS(select 1 from pg_catalog.pg_cast where
         castsource = $1 and casttarget = $2 and
-        castfunc = 0) OR
+        castmethod = 'b') OR
  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
   EXISTS(select 1 from pg_catalog.pg_type where
          oid = $1 and typelem != 0 and typlen = -1))
@@ -262,9 +262,20 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
 -- oidjoins test).
 SELECT *
 FROM pg_cast c
-WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
+WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
+    OR castmethod NOT IN ('f', 'b' ,'i');
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
+(0 rows)
+
+-- Check that castfunc is nonzero only for cast methods that need a function,
+-- and zero otherwise
+SELECT *
+FROM pg_cast c
+WHERE (castmethod = 'f' AND castfunc = 0)
+   OR (castmethod IN ('b', 'i') AND castfunc <> 0);
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for casts to/from the same type that aren't length coercion functions.
@@ -273,15 +284,15 @@ WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
 SELECT *
 FROM pg_cast c
 WHERE castsource = casttarget AND castfunc = 0;
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
 (0 rows)
 
 SELECT c.*
 FROM pg_cast c, pg_proc p
 WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for cast functions that don't have the right signature.  The
@@ -299,8 +310,8 @@ WHERE c.castfunc = p.oid AND
              OR (c.castsource = 'character'::regtype AND
                  p.proargtypes[0] = 'text'::regtype))
      OR NOT binary_coercible(p.prorettype, c.casttarget));
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
 (0 rows)
 
 SELECT c.*
@@ -308,8 +319,8 @@ FROM pg_cast c, pg_proc p
 WHERE c.castfunc = p.oid AND
     ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
      (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for binary compatible casts that do not have the reverse
@@ -324,19 +335,19 @@ WHERE c.castfunc = p.oid AND
 -- texttoxml(), which does an XML syntax check.
 SELECT *
 FROM pg_cast c
-WHERE c.castfunc = 0 AND
+WHERE c.castmethod = 'b' AND
     NOT EXISTS (SELECT 1 FROM pg_cast k
-                WHERE k.castfunc = 0 AND
+                WHERE k.castmethod = 'b' AND
                     k.castsource = c.casttarget AND
                     k.casttarget = c.castsource);
- castsource | casttarget | castfunc | castcontext 
-------------+------------+----------+-------------
-         25 |       1042 |        0 | i
-       1043 |       1042 |        0 | i
-        650 |        869 |        0 | i
-        142 |         25 |        0 | a
-        142 |       1043 |        0 | a
-        142 |       1042 |        0 | a
+ castsource | casttarget | castfunc | castcontext | castmethod 
+------------+------------+----------+-------------+------------
+         25 |       1042 |        0 | i           | b
+       1043 |       1042 |        0 | i           | b
+        650 |        869 |        0 | i           | b
+        142 |         25 |        0 | a           | b
+        142 |       1043 |        0 | a           | b
+        142 |       1042 |        0 | a           | b
 (6 rows)
 
 -- **************** pg_operator ****************
index 57c2cad95151649f0fe9c0ad2df14061749b27bb..c254a8b6cb0cca682402ec9b69c469b01b09e58b 100644 (file)
@@ -25,7 +25,7 @@ create function binary_coercible(oid, oid) returns bool as $$
 SELECT ($1 = $2) OR
  EXISTS(select 1 from pg_catalog.pg_cast where
         castsource = $1 and casttarget = $2 and
-        castfunc = 0 and castcontext = 'i') OR
+        castmethod = 'b' and castcontext = 'i') OR
  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
   EXISTS(select 1 from pg_catalog.pg_type where
          oid = $1 and typelem != 0 and typlen = -1))
@@ -37,7 +37,7 @@ create function physically_coercible(oid, oid) returns bool as $$
 SELECT ($1 = $2) OR
  EXISTS(select 1 from pg_catalog.pg_cast where
         castsource = $1 and casttarget = $2 and
-        castfunc = 0) OR
+        castmethod = 'b') OR
  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
   EXISTS(select 1 from pg_catalog.pg_type where
          oid = $1 and typelem != 0 and typlen = -1))
@@ -214,7 +214,16 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
 
 SELECT *
 FROM pg_cast c
-WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i');
+WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
+    OR castmethod NOT IN ('f', 'b' ,'i');
+
+-- Check that castfunc is nonzero only for cast methods that need a function,
+-- and zero otherwise
+
+SELECT *
+FROM pg_cast c
+WHERE (castmethod = 'f' AND castfunc = 0)
+   OR (castmethod IN ('b', 'i') AND castfunc <> 0);
 
 -- Look for casts to/from the same type that aren't length coercion functions.
 -- (We assume they are length coercions if they take multiple arguments.)
@@ -267,9 +276,9 @@ WHERE c.castfunc = p.oid AND
 
 SELECT *
 FROM pg_cast c
-WHERE c.castfunc = 0 AND
+WHERE c.castmethod = 'b' AND
     NOT EXISTS (SELECT 1 FROM pg_cast k
-                WHERE k.castfunc = 0 AND
+                WHERE k.castmethod = 'b' AND
                     k.castsource = c.casttarget AND
                     k.casttarget = c.castsource);