> On Feb 2, 2026, at 08:42, Álvaro Herrera <[email protected]> wrote:
> 
> Hi,
> 
> There have been mentions of turning Form_pg_class->relkind into an enum,
> so that we can have compilers provide some more help with
> switch(relkind) blocks.  Here's a quick experiment with that.

Sounds like a correct direction to go overall.

> 
> The most annoying part of this is that query-generating code uses
> CppAsString2() to turn the char values into strings.  Making that code
> use the enum values directly is quite messy, so before spending real
> time into making that correct, I just added some ugly #define
> RELKIND_x_STR macros, to substitute the uses of the other construct.
> This is not intended to be final form.  This is 0001+0002, both
> mechanical[1].

I’m not a big fan of the new RELKIND_x_STR macros. Not only because there 
aren’t many similar macros in the existing codebase, but more importantly 
because RELKIND_x_STR is effectively decoupled from the enum values RELKIND_x. 
It would be easy in the future to add a new enum value and forget to introduce 
the corresponding _STR macro.

What do you think about an approach like this instead?
```
#define RELKIND_CHAR_RELATION ‘r’
…

typedef enum
{
    RELKIND_RELATION = RELKIND_CHAR_RELATION,
    ...
} Relkind;
```

This keeps the enum values mechanically tied to the underlying character 
constants. When a new enum value is added, it’s much harder to forget defining 
the corresponding _CHAR_ macro. With this approach, patch 0002 would only need 
to replace RELKIND_x with RELKIND_CHAR_x.

> 
> 0003 is the backend-side change.  This looks generally reasonable,
> though I'm annoyed that I couldn't find a way to coerce the compiler
> into telling me if I had missed some spot.  I didn't change any
> switch(relkind) blocks (except one in pg_overexplain which causes a
> compiler warning for trying to use the non-existent '\0' value), but I
> played with a couple of them by removing the default clauses and indeed
> we now get warnings for missing cases.
> 
> Of course, pg_class.relkind itself (the on-disk catalog) continues to be
> a single char with the same values as before.
> 
> Does this look more or less a direction we'd like to go in?
> 
> [1] git grep --files-with-matches 'CppAsString2(RELKIND' | xargs -n1 perl -pi 
> -e 's/CppAsString2\((RELKIND[^)]*)\)/$1_STR/g'
> 

One minor naming question as well: why Relkind instead of RelKind? There’s 
already a type named PublicationRelKind, and we also have several other types 
following a similar pattern, like RelAggInfo, RelCacheInitLock, RelFileNumber, 
etc. Using RelKind would seem a bit more consistent with those.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/






Reply via email to