Re: Current enums patch - Mailing list pgsql-patches

From Andrew Dunstan
Subject Re: Current enums patch
Date
Msg-id 460EB131.7040603@dunslane.net
Whole thread Raw
In response to Re: Current enums patch  (Peter Eisentraut <peter_e@gmx.net>)
Responses Re: Current enums patch
Re: Current enums patch
List pgsql-patches
Peter Eisentraut wrote:
> Am Dienstag, 27. März 2007 03:36 schrieb Tom Dunstan:
>
>> Here's the current version of the enums patch. Not much change from last
>> time, the only thought-inducing stuff was fixing up some macros that
>> changed with the VARLENA changes, and adding a regression test to do
>> basic checking of RI behavior, after the discussions that we had
>> recently on the ri_trigger stuff with generic types. The actual behavior
>> was fixed by Tom's earlier patch, so this is just a sanity check.
>>
>
> Your patch doesn't compile anymore.
>
> ccache cc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Winline -Wdeclaration-after-statement -Wendif-labels
-fno-strict-aliasing-g -I. -I../../../src/include -D_GNU_SOURCE -I/usr/include/libxml2   -c -o parse_coerce.o
parse_coerce.c-MMD -MP -MF .deps/parse_coerce.Po 
> parse_coerce.c: In function 'can_coerce_type':
> parse_coerce.c:460: error: too few arguments to function 'find_coercion_pathway'
> parse_coerce.c: In function 'find_coercion_pathway':
> parse_coerce.c:1817: error: too few arguments to function 'find_coercion_pathway'
> parse_coerce.c:1822: error: too few arguments to function 'find_coercion_pathway'
>
> This was only changed a few days ago, so you need to update your patch.
>
>

Peter,

If you want to review or test the feature, the attached patch can be
used as a replacement for the portion that affects parse_coerce.c, and
with this it compiles and passes regression. I think it's correct but it
should still be OKed by at least one Tom. :-)

cheers

andrew
Index: parse_coerce.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v
retrieving revision 2.152
diff -c -r2.152 parse_coerce.c
*** parse_coerce.c    27 Mar 2007 23:21:10 -0000    2.152
--- parse_coerce.c    31 Mar 2007 18:53:08 -0000
***************
*** 132,137 ****
--- 132,138 ----
      }
      if (targetTypeId == ANYOID ||
          targetTypeId == ANYELEMENTOID ||
+         targetTypeId == ANYENUMOID ||
          (targetTypeId == ANYARRAYOID && inputTypeId != UNKNOWNOID))
      {
          /*
***************
*** 406,414 ****
          if (targetTypeId == ANYOID)
              continue;

!         /* accept if target is ANYARRAY or ANYELEMENT, for now */
          if (targetTypeId == ANYARRAYOID ||
!             targetTypeId == ANYELEMENTOID)
          {
              have_generics = true;        /* do more checking later */
              continue;
--- 407,416 ----
          if (targetTypeId == ANYOID)
              continue;

!         /* accept if target is ANYARRAY, ANYELEMENT or ANYENUM, for now */
          if (targetTypeId == ANYARRAYOID ||
!             targetTypeId == ANYELEMENTOID ||
!             targetTypeId == ANYENUMOID)
          {
              have_generics = true;        /* do more checking later */
              continue;
***************
*** 451,456 ****
--- 453,466 ----
              continue;

          /*
+          * If input is an enum, can ANYENUM be cast to target?
+          */
+         if (is_type_enum(inputTypeId) &&
+             find_coercion_pathway(targetTypeId, ANYENUMOID,
+                                   ccontext, &funcId, &arrayCoerce))
+             continue;
+
+         /*
           * Else, cannot coerce at this argument position
           */
          return false;
***************
*** 1070,1076 ****
      Oid            array_typeid = InvalidOid;
      Oid            array_typelem;
      bool        have_anyelement = false;
!
      /*
       * Loop through the arguments to see if we have any that are ANYARRAY or
       * ANYELEMENT. If so, require the actual types to be self-consistent
--- 1080,1086 ----
      Oid            array_typeid = InvalidOid;
      Oid            array_typelem;
      bool        have_anyelement = false;
!     bool        have_enum = false;
      /*
       * Loop through the arguments to see if we have any that are ANYARRAY or
       * ANYELEMENT. If so, require the actual types to be self-consistent
***************
*** 1079,1085 ****
      {
          Oid            actual_type = actual_arg_types[j];

!         if (declared_arg_types[j] == ANYELEMENTOID)
          {
              have_anyelement = true;
              if (actual_type == UNKNOWNOID)
--- 1089,1096 ----
      {
          Oid            actual_type = actual_arg_types[j];

!         if (declared_arg_types[j] == ANYELEMENTOID ||
!             declared_arg_types[j] == ANYENUMOID)
          {
              have_anyelement = true;
              if (actual_type == UNKNOWNOID)
***************
*** 1087,1092 ****
--- 1098,1105 ----
              if (OidIsValid(elem_typeid) && actual_type != elem_typeid)
                  return false;
              elem_typeid = actual_type;
+             if (declared_arg_types[j] == ANYENUMOID)
+                 have_enum = true;
          }
          else if (declared_arg_types[j] == ANYARRAYOID)
          {
***************
*** 1127,1132 ****
--- 1140,1151 ----
          }
      }

+     if (have_enum)
+     {
+         /* is the given type as enum type? */
+         return is_type_enum(elem_typeid);
+     }
+
      /* Looks valid */
      return true;
  }
***************
*** 1180,1186 ****
      Oid            elem_typeid = InvalidOid;
      Oid            array_typeid = InvalidOid;
      Oid            array_typelem;
!     bool        have_anyelement = (rettype == ANYELEMENTOID);

      /*
       * Loop through the arguments to see if we have any that are ANYARRAY or
--- 1199,1206 ----
      Oid            elem_typeid = InvalidOid;
      Oid            array_typeid = InvalidOid;
      Oid            array_typelem;
!     bool        have_anyelement = (rettype == ANYELEMENTOID ||
!                                    rettype == ANYENUMOID);

      /*
       * Loop through the arguments to see if we have any that are ANYARRAY or
***************
*** 1190,1196 ****
      {
          Oid            actual_type = actual_arg_types[j];

!         if (declared_arg_types[j] == ANYELEMENTOID)
          {
              have_generics = have_anyelement = true;
              if (actual_type == UNKNOWNOID)
--- 1210,1217 ----
      {
          Oid            actual_type = actual_arg_types[j];

!         if (declared_arg_types[j] == ANYELEMENTOID ||
!             declared_arg_types[j] == ANYENUMOID)
          {
              have_generics = have_anyelement = true;
              if (actual_type == UNKNOWNOID)
***************
*** 1289,1295 ****
              if (actual_type != UNKNOWNOID)
                  continue;

!             if (declared_arg_types[j] == ANYELEMENTOID)
                  declared_arg_types[j] = elem_typeid;
              else if (declared_arg_types[j] == ANYARRAYOID)
              {
--- 1310,1317 ----
              if (actual_type != UNKNOWNOID)
                  continue;

!             if (declared_arg_types[j] == ANYELEMENTOID ||
!                 declared_arg_types[j] == ANYENUMOID)
                  declared_arg_types[j] = elem_typeid;
              else if (declared_arg_types[j] == ANYARRAYOID)
              {
***************
*** 1323,1329 ****
      }

      /* if we return ANYELEMENTOID use the appropriate argument type */
!     if (rettype == ANYELEMENTOID)
          return elem_typeid;

      /* we don't return a generic type; send back the original return type */
--- 1345,1351 ----
      }

      /* if we return ANYELEMENTOID use the appropriate argument type */
!     if (rettype == ANYELEMENTOID || rettype == ANYENUMOID)
          return elem_typeid;

      /* we don't return a generic type; send back the original return type */
***************
*** 1362,1368 ****
                                  format_type_be(context_actual_type))));
              return context_actual_type;
          }
!         else if (context_declared_type == ANYELEMENTOID)
          {
              /* Use the array type corresponding to actual type */
              Oid            array_typeid = get_array_type(context_actual_type);
--- 1384,1391 ----
                                  format_type_be(context_actual_type))));
              return context_actual_type;
          }
!         else if (context_declared_type == ANYELEMENTOID ||
!                  context_declared_type == ANYENUMOID)
          {
              /* Use the array type corresponding to actual type */
              Oid            array_typeid = get_array_type(context_actual_type);
***************
*** 1375,1381 ****
              return array_typeid;
          }
      }
!     else if (declared_type == ANYELEMENTOID)
      {
          if (context_declared_type == ANYARRAYOID)
          {
--- 1398,1404 ----
              return array_typeid;
          }
      }
!     else if (declared_type == ANYELEMENTOID || declared_type == ANYENUMOID)
      {
          if (context_declared_type == ANYARRAYOID)
          {
***************
*** 1389,1395 ****
                                  format_type_be(context_actual_type))));
              return array_typelem;
          }
!         else if (context_declared_type == ANYELEMENTOID)
          {
              /* Use the actual type; it doesn't matter if array or not */
              return context_actual_type;
--- 1412,1419 ----
                                  format_type_be(context_actual_type))));
              return array_typelem;
          }
!         else if (context_declared_type == ANYELEMENTOID ||
!                  context_declared_type == ANYENUMOID)
          {
              /* Use the actual type; it doesn't matter if array or not */
              return context_actual_type;
***************
*** 1502,1507 ****
--- 1526,1532 ----
          case (INTERNALOID):
          case (OPAQUEOID):
          case (ANYELEMENTOID):
+         case (ANYENUMOID):
              result = GENERIC_TYPE;
              break;

***************
*** 1634,1639 ****
--- 1659,1668 ----
      if (srctype == targettype)
          return true;

+     /* Check for enums */
+     if (targettype == ANYENUMOID)
+         return is_type_enum(srctype);
+
      /* If srctype is a domain, reduce to its base type */
      if (OidIsValid(srctype))
          srctype = getBaseType(srctype);
***************
*** 1742,1747 ****
--- 1771,1790 ----

          ReleaseSysCache(tuple);
      }
+     /*
+      * Deal with enums. If the input type is an enum, and we haven't found
+      * an explicit pg_cast entry above, retry with ANYENUM.
+      */
+     else if (is_type_enum(sourceTypeId))
+     {
+         result = find_coercion_pathway(targetTypeId, ANYENUMOID,
+                                        ccontext, funcid, arrayCoerce);
+     }
+     else if (is_type_enum(targetTypeId))
+     {
+         result = find_coercion_pathway(ANYENUMOID, sourceTypeId,
+                                        ccontext, funcid, arrayCoerce);
+     }
      else
      {
          /*
***************
*** 1777,1782 ****
--- 1820,1826 ----
                  result = true;
              }
          }
+
      }

      return result;

pgsql-patches by date:

Previous
From: Magnus Hagander
Date:
Subject: Re: COPY-able sql log outputs
Next
From: Tom Lane
Date:
Subject: Re: Current enums patch