On 2026-Aug-17, Peter Eisentraut wrote:
> There are, depending on how you count, a few to many other ternary types
> used throughout the tree, and it's not clear why this one should be the
> standard one now.
I asked Claude which ternaries we have. The response listed three, and
it started with:
pg_ternary — src/include/postgres.h
The canonical/general-purpose one. Values: PG_TERNARY_FALSE (0),
PG_TERNARY_TRUE (1), PG_TERNARY_UNSET (-1). Comment explicitly describes
it as a boolean with an extra "unset" value.
It's already considered the canonical one! That's a great start.
It then said
trivalue — src/bin/pg_dump/pg_backup.h
Used by pg_dump / client tools for command-line options. Values:
TRI_DEFAULT, TRI_NO, TRI_YES.
PGTernaryBool — src/interfaces/libpq/libpq-int.h (and an identical
copy in src/interfaces/libpq-oauth/oauth-utils.h)
A libpq internal "boolean plus not-known" for GUCs it may have to
fetch. Values: PG_BOOL_UNKNOWN (0), PG_BOOL_YES, PG_BOOL_NO.
That's the complete list it produced.
> At least if so that should have involved some discussion
> and analysis on the other ones. There are also some tradeoffs about how
> this type should be designed. This particular one uses 0 and 1 for false
> and true, and -1 for unset. Others use 0 for unset and other values for
> false and true. Maybe this choice is useful for this particular use, but we
> shouldn't impose it on everyone.
I think you're talking about the libpq one (PGTernaryBool), which dates
back to commit ee28cacf619f and was defined in libpq-int.h.
> Independent of that, I don't understand why this was put into postgres.h
> instead of c.h. It's not particular to backend code, as far as I can tell.
Right, it's not. It felt a bit out of place in c.h to me, and I didn't
see the argument for exposing it wider than postgres.h, but at the same
time it seemed to me that a notion this common can perfectly well use a
single central definition rather than have each module define the same
thing.
We have a handful of enums all called "trivalue" in various clients
programs, with the same definitions, and that doesn't seem great to me --
quite the opposite in fact. If we move pg_ternary to c.h and add
aliases TRI_YES / NO / DEFAULT, then we can remove the repetitive enum
typedefs and we'd probably be in a better position.
> I think it would be better to rename this to something like relopt_ternary
> and move it to access/reloptions.h.
I'm not sure what we gain from doing that. If there's generalized
opposition to having it in postgres.h, I'm open to renaming it as
suggested and moving it there.
> If we want to consolidate all ternary types, that might be useful, but it
> should be an explicit discussion.
The others I found were:
/*
* Represents whether a header line must match the actual names
* (which implies "true"), and whether it should be present.
*/
#define COPY_HEADER_MATCH -1
#define COPY_HEADER_FALSE 0
#define COPY_HEADER_TRUE 1
and
#define GIN_FALSE 0 /* item is not present / does not match */
#define GIN_TRUE 1 /* item is present / matches */
#define GIN_MAYBE 2 /* don't know if item is present / don't know
* if matches */
and it didn't seem that they had semantics similar enough to make them
use the new enum.
--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
"Sallah, I said NO camels! That's FIVE camels; can't you count?"
(Indiana Jones)