Re: Working with PostgreSQL enums in C code

From: Joseph Adams <joeyadams3(dot)14159(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Working with PostgreSQL enums in C code
Date: 2010-06-07 21:16:12
Message-ID: AANLkTiniZAhj3p015IqXMFJ9RpyJ_KCjOALuWFKWsFBx@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, May 28, 2010 at 9:47 AM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Robert Haas <robertmhaas(at)gmail(dot)com> writes:
>> On Fri, May 28, 2010 at 12:07 AM, Joseph Adams
>> <joeyadams3(dot)14159(at)gmail(dot)com> wrote:
>>> 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 .
>
>> PG_RETURN macros shouldn't do any nontrivial processing (see the
>> existing ones for references).
>
> Yeah, that was my first reaction too.  If we don't already have one,
> it would be appropriate to provide a "lookup enum value" function
> (functionally about the same as enum_in, but designed to be called
> conveniently from C).  Then, if you needed to work from a textual
> enum label, you'd call that function and then PG_RETURN_OID.

Here is the function I wrote to look up enum values:

Oid enum_label_to_oid(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;
}

If this were added to PostgreSQL proper, what source/header files
would it make sense to put it in? enum.c/builtins.h ?

> However, for a built-in enum type, I agree with Robert's solution of
> just #define-ing fixed OIDs for the values of the type.

I don't know if the JSON datatype will be a contrib module or built-in
yet, but if it were contrib, would it still be better to use fixed
OIDs anyway? One issue with setting this precedent is that new
contrib modules using enums wouldn't be compatible with older versions
of PostgreSQL. One idea might be to insert extend CREATE TYPE name AS
ENUM so OIDs can be specified explicitly, but then that could lead to
OID clashes. That would be a really messy problem for users.

By the way, just curious: why can't the internal representation of an
enum just be an INT starting from 0 by default, like in C? That would
make a heck of a lot more sense, in my opinion. It might also allow
users to do things like this in the future:

CREATE TYPE number AS ENUM ('one' = 1, 'two' = 2, 'three' = 3);

Joey Adams

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Greg Stark 2010-06-07 21:23:22 Re: Functional dependencies and GROUP BY
Previous Message Yeb Havinga 2010-06-07 19:20:55 Re: Re: [RFC][PATCH]: CRC32 is limiting at COPY/CTAS/INSERT ... SELECT + speeding it up