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;
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
http://www.postgresql.org/about/donate