I encountered a situation while implementing JSON support where I needed to return an enum value from a C function. To clarify, here's the SQL:
CREATE TYPE json_type_t AS ENUM ('null', 'string', 'number', 'bool', 'object', 'array'); CREATE OR REPLACE FUNCTION json_type(json) RETURNS json_type_t AS 'MODULE_PATHNAME','json_get_type' LANGUAGE C STRICT IMMUTABLE; I initially tried looking for another function returning an enum in the PostgreSQL source tree, but I couldn't find any. I guess this is because enums are a relatively new feature in PostgreSQL. I learned that to return an enum value from C, one needs to return the OID of the right row of the pg_enum table. I eventually managed to write the code below, which is mostly based on the enum_in function in src/backend/utils/adt/enum.c . #define PG_RETURN_ENUM(typname, label) return enumLabelToOid(typname, label) static Oid enumLabelToOid(const char *typname, const char *label) { Oid enumtypoid; HeapTuple tup; Oid ret; enumtypoid = TypenameGetTypid(typname); Assert(OidIsValid(enumtypoid)); tup = SearchSysCache2(ENUMTYPOIDNAME, ObjectIdGetDatum(enumtypoid), CStringGetDatum(label)); Assert(HeapTupleIsValid(tup)); ret = HeapTupleGetOid(tup); ReleaseSysCache(tup); return ret; } Feel free to nitpick the code above, as I'm still learning. Note that I replaced the more robust validity checks of enum_in with (quicker?) asserts, with the assumption that correct programs would only pass valid values to PG_RETURN_ENUM . The code using the method above can be found here: http://git.postgresql.org/gitweb?p=json-datatype.git;a=tree;f=contrib/json;h=1dd813da4016b31f35cb39b01c6d5f0999da672e;hb=092fa046f95580dd7906a07370ca401692a1f818 . My testcases passed, so everything seems to work. I suppose my PG_RETURN_ENUM macro is nice and simple, except for the fact that the coder has to keep an enum names table in sync with the SQL code and the C code. However, going the other way around (PG_GETARG_ENUM) would need access to that enum names table. Hence, it'd make sense to have macros for defining this table so both PG_RETURN_ENUM and PG_GETARG_ENUM can reference it. I believe that these macros would be a useful addition to the PostgreSQL function manager API, as they would provide a decent way to receive and return custom enums from C code. Anyone agree/disagree? Joey Adams -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers