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

Reply via email to