Tom Lane wrote:

Andrew's idea of using the enum ordinal value would meet that test, but
at least with the current layout of pg_enum it would be quite expensive
to do the conversion in either direction --- you'd have to fetch
multiple catalog rows.  I think we'd have to add another column showing
the ordinal value, and put an index on it, to make I/O reasonably fast.
Doesn't really seem worth it.

                        

Yeah. I think we should treat enums just as we do text, for this purpose.

Here's a patch (minus catalog bump) which I think does that.

cheers

andrew
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.106
diff -c -r1.106 typecmds.c
*** src/backend/commands/typecmds.c	20 Jun 2007 18:15:49 -0000	1.106
--- src/backend/commands/typecmds.c	31 Aug 2007 14:31:05 -0000
***************
*** 1039,1046 ****
  				   DEFAULT_TYPDELIM,	/* array element delimiter */
  				   F_ENUM_IN,		/* input procedure */
  				   F_ENUM_OUT,		/* output procedure */
! 				   InvalidOid,		/* receive procedure - none */
! 				   InvalidOid,		/* send procedure - none */
  				   InvalidOid,		/* typmodin procedure - none */
  				   InvalidOid,		/* typmodout procedure - none */
  				   InvalidOid,		/* analyze procedure - default */
--- 1039,1046 ----
  				   DEFAULT_TYPDELIM,	/* array element delimiter */
  				   F_ENUM_IN,		/* input procedure */
  				   F_ENUM_OUT,		/* output procedure */
! 				   F_ENUM_RECV,		/* receive procedure */
! 				   F_ENUM_SEND,		/* send procedure */
  				   InvalidOid,		/* typmodin procedure - none */
  				   InvalidOid,		/* typmodout procedure - none */
  				   InvalidOid,		/* analyze procedure - default */
Index: src/backend/utils/adt/enum.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/enum.c,v
retrieving revision 1.3
diff -c -r1.3 enum.c
*** src/backend/utils/adt/enum.c	5 Jun 2007 21:31:06 -0000	1.3
--- src/backend/utils/adt/enum.c	31 Aug 2007 14:31:05 -0000
***************
*** 19,24 ****
--- 19,26 ----
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
  #include "utils/syscache.h"
+ #include "libpq/pqformat.h"
+ #include "miscadmin.h"
  
  
  static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper);
***************
*** 86,91 ****
--- 88,160 ----
  	PG_RETURN_CSTRING(result);
  }
  
+ /* Binary I/O support */
+ Datum
+ enum_recv(PG_FUNCTION_ARGS)
+ {
+ 	StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
+ 	Oid enumtypoid = PG_GETARG_OID(1);
+ 	Oid enumoid;
+ 	HeapTuple tup;
+ 	char       *name;
+ 	int         nbytes;
+ 
+ 	name = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
+ 
+ 	/* must check length to prevent Assert failure within SearchSysCache */
+ 	if (strlen(name) >= NAMEDATALEN)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ 				 errmsg("invalid input value for enum %s: \"%s\"",
+ 						format_type_be(enumtypoid),
+ 						name)));
+ 
+ 	tup = SearchSysCache(ENUMTYPOIDNAME,
+ 						 ObjectIdGetDatum(enumtypoid),
+ 						 CStringGetDatum(name),
+ 						 0, 0);
+ 	if (!HeapTupleIsValid(tup))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ 				 errmsg("invalid input value for enum %s: \"%s\"",
+ 						format_type_be(enumtypoid),
+ 						name)));
+ 
+ 	enumoid = HeapTupleGetOid(tup);
+ 
+ 	ReleaseSysCache(tup);
+ 
+ 	pfree(name);
+ 
+ 	PG_RETURN_OID(enumoid);
+ }
+ 
+ Datum
+ enum_send(PG_FUNCTION_ARGS)
+ {
+ 	Oid enumval = PG_GETARG_OID(0);
+ 	StringInfoData buf;
+ 	HeapTuple tup;
+ 	Form_pg_enum en;
+ 
+ 	tup = SearchSysCache(ENUMOID,
+ 						 ObjectIdGetDatum(enumval),
+ 						 0, 0, 0);
+ 	if (!HeapTupleIsValid(tup))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
+ 				 errmsg("invalid internal value for enum: %u",
+ 						enumval)));
+ 	en = (Form_pg_enum) GETSTRUCT(tup);
+ 
+ 	pq_begintypsend(&buf);
+ 	pq_sendtext(&buf, NameStr(en->enumlabel), strlen(NameStr(en->enumlabel)));
+ 
+ 	ReleaseSysCache(tup);
+ 
+ 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+ }
+ 
  /* Comparison functions and related */
  
  Datum
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.465
diff -c -r1.465 pg_proc.h
*** src/include/catalog/pg_proc.h	27 Aug 2007 01:39:24 -0000	1.465
--- src/include/catalog/pg_proc.h	31 Aug 2007 14:31:06 -0000
***************
*** 4134,4139 ****
--- 4134,4141 ----
  DATA(insert OID = 3529 (  enum_last		PGNSP PGUID 12 1 0 f f f f s 1 3500 "3500" _null_ _null_ _null_ enum_last - _null_ ));
  DATA(insert OID = 3530 (  enum_range	PGNSP PGUID 12 1 0 f f f f s 2 2277 "3500 3500" _null_ _null_ _null_ enum_range_bounds - _null_ ));
  DATA(insert OID = 3531 (  enum_range	PGNSP PGUID 12 1 0 f f f f s 1 2277 "3500" _null_ _null_ _null_ enum_range_all - _null_ ));
+ DATA(insert OID = 3532 (  enum_recv	    PGNSP PGUID 12 1 0 f f t f s 2 3500 "2275 26" _null_ _null_ _null_ enum_recv - _null_ ));
+ DATA(insert OID = 3533 (  enum_send	    PGNSP PGUID 12 1 0 f f t f s 1 17   "3500" _null_ _null_ _null_ enum_send - _null_ ));
  
  /* text search stuff */
  DATA(insert OID =  3610 (  tsvectorin			PGNSP PGUID 12 1 0 f f t f i 1 3614 "2275" _null_ _null_ _null_ tsvectorin - _null_ ));
Index: src/include/utils/builtins.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.301
diff -c -r1.301 builtins.h
*** src/include/utils/builtins.h	27 Aug 2007 01:39:25 -0000	1.301
--- src/include/utils/builtins.h	31 Aug 2007 14:31:07 -0000
***************
*** 107,112 ****
--- 107,114 ----
  /* enum.c */
  extern Datum enum_in(PG_FUNCTION_ARGS);
  extern Datum enum_out(PG_FUNCTION_ARGS);
+ extern Datum enum_recv(PG_FUNCTION_ARGS);
+ extern Datum enum_send(PG_FUNCTION_ARGS);
  extern Datum enum_lt(PG_FUNCTION_ARGS);
  extern Datum enum_le(PG_FUNCTION_ARGS);
  extern Datum enum_eq(PG_FUNCTION_ARGS);
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to