For the sake of discussion, here is what the enum approach would look like.

-- 
nathan
>From f108e6c7e07c4148f097fbfd612cf79db60c5acd Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nat...@postgresql.org>
Date: Mon, 24 Mar 2025 12:46:26 -0500
Subject: [PATCH 1/1] change vacuum_truncate relopt to enum

---
 src/backend/access/common/reloptions.c | 50 ++++++++++++++------------
 src/backend/commands/vacuum.c          |  4 +--
 src/include/access/reloptions.h        |  1 -
 src/include/utils/rel.h                | 11 ++++--
 src/tools/pgindent/typedefs.list       |  1 +
 5 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/src/backend/access/common/reloptions.c 
b/src/backend/access/common/reloptions.c
index 645b5c00467..71a44d4cf1e 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -147,15 +147,6 @@ static relopt_bool boolRelOpts[] =
                },
                false
        },
-       {
-               {
-                       "vacuum_truncate",
-                       "Enables vacuum to truncate empty pages at the end of 
this table",
-                       RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
-                       ShareUpdateExclusiveLock
-               },
-               true
-       },
        {
                {
                        "deduplicate_items",
@@ -524,6 +515,20 @@ static relopt_enum_elt_def viewCheckOptValues[] =
        {(const char *) NULL}           /* list terminator */
 };
 
+/* values from StdRdOptBool */
+static relopt_enum_elt_def StdRdOptBoolValues[] =
+{
+       {"on", STDRD_OPTION_BOOL_ON},
+       {"off", STDRD_OPTION_BOOL_OFF},
+       {"true", STDRD_OPTION_BOOL_ON},
+       {"false", STDRD_OPTION_BOOL_OFF},
+       {"yes", STDRD_OPTION_BOOL_ON},
+       {"no", STDRD_OPTION_BOOL_OFF},
+       {"1", STDRD_OPTION_BOOL_ON},
+       {"0", STDRD_OPTION_BOOL_OFF},
+       {(const char *) NULL}           /* list terminator */
+};
+
 static relopt_enum enumRelOpts[] =
 {
        {
@@ -559,6 +564,17 @@ static relopt_enum enumRelOpts[] =
                VIEW_OPTION_CHECK_OPTION_NOT_SET,
                gettext_noop("Valid values are \"local\" and \"cascaded\".")
        },
+       {
+               {
+                       "vacuum_truncate",
+                       "Enables vacuum to truncate empty pages at the end of 
this table",
+                       RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+                       ShareUpdateExclusiveLock
+               },
+               StdRdOptBoolValues,
+               STDRD_OPTION_BOOL_NOT_SET,
+               gettext_noop("Valid values are \"on\" and \"off\".")
+       },
        /* list terminator */
        {{NULL}}
 };
@@ -1779,17 +1795,6 @@ fillRelOptions(void *rdopts, Size basesize,
                                char       *itempos = ((char *) rdopts) + 
elems[j].offset;
                                char       *string_val;
 
-                               /*
-                                * If isset_offset is provided, store whether 
the reloption is
-                                * set there.
-                                */
-                               if (elems[j].isset_offset > 0)
-                               {
-                                       char       *setpos = ((char *) rdopts) 
+ elems[j].isset_offset;
-
-                                       *(bool *) setpos = options[i].isset;
-                               }
-
                                switch (options[i].gen->type)
                                {
                                        case RELOPT_TYPE_BOOL:
@@ -1911,8 +1916,8 @@ default_reloptions(Datum reloptions, bool validate, 
relopt_kind kind)
                offsetof(StdRdOptions, parallel_workers)},
                {"vacuum_index_cleanup", RELOPT_TYPE_ENUM,
                offsetof(StdRdOptions, vacuum_index_cleanup)},
-               {"vacuum_truncate", RELOPT_TYPE_BOOL,
-               offsetof(StdRdOptions, vacuum_truncate), offsetof(StdRdOptions, 
vacuum_truncate_set)},
+               {"vacuum_truncate", RELOPT_TYPE_ENUM,
+               offsetof(StdRdOptions, vacuum_truncate)},
                {"vacuum_max_eager_freeze_failure_rate", RELOPT_TYPE_REAL,
                offsetof(StdRdOptions, vacuum_max_eager_freeze_failure_rate)}
        };
@@ -1992,7 +1997,6 @@ build_local_reloptions(local_relopts *relopts, Datum 
options, bool validate)
                elems[i].optname = opt->option->name;
                elems[i].opttype = opt->option->type;
                elems[i].offset = opt->offset;
-               elems[i].isset_offset = 0;      /* not supported for local 
relopts yet */
 
                i++;
        }
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index f0a7b87808d..7c725ea4b76 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2206,9 +2206,9 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams 
*params,
        {
                StdRdOptions *opts = (StdRdOptions *) rel->rd_options;
 
-               if (opts && opts->vacuum_truncate_set)
+               if (opts && opts->vacuum_truncate != STDRD_OPTION_BOOL_NOT_SET)
                {
-                       if (opts->vacuum_truncate)
+                       if (opts->vacuum_truncate == STDRD_OPTION_BOOL_ON)
                                params->truncate = VACOPTVALUE_ENABLED;
                        else
                                params->truncate = VACOPTVALUE_DISABLED;
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 146aed47c2d..43445cdcc6c 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -152,7 +152,6 @@ typedef struct
        const char *optname;            /* option's name */
        relopt_type opttype;            /* option's datatype */
        int                     offset;                 /* offset of field in 
result struct */
-       int                     isset_offset;   /* if > 0, offset of "is set" 
field */
 } relopt_parse_elt;
 
 /* Local reloption definition */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index d94fddd7cef..d0c01f69abf 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -334,6 +334,14 @@ typedef enum StdRdOptIndexCleanup
        STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
 } StdRdOptIndexCleanup;
 
+/* useful for Boolean relopts when we need to determine whether it's set */
+typedef enum StdRdOptBool
+{
+       STDRD_OPTION_BOOL_NOT_SET = 0,
+       STDRD_OPTION_BOOL_ON,
+       STDRD_OPTION_BOOL_OFF,
+} StdRdOptBool;
+
 typedef struct StdRdOptions
 {
        int32           vl_len_;                /* varlena header (do not touch 
directly!) */
@@ -343,8 +351,7 @@ typedef struct StdRdOptions
        bool            user_catalog_table; /* use as an additional catalog 
relation */
        int                     parallel_workers;       /* max number of 
parallel workers */
        StdRdOptIndexCleanup vacuum_index_cleanup;      /* controls index 
vacuuming */
-       bool            vacuum_truncate;        /* enables vacuum to truncate a 
relation */
-       bool            vacuum_truncate_set;    /* whether vacuum_truncate is 
set */
+       StdRdOptBool vacuum_truncate;   /* enables vacuum to truncate a 
relation */
 
        /*
         * Fraction of pages in a relation that vacuum can eagerly scan and fail
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 3fbf5a4c212..ac530fb40e7 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2818,6 +2818,7 @@ StatsData
 StatsElem
 StatsExtInfo
 StdAnalyzeData
+StdRdOptBool
 StdRdOptIndexCleanup
 StdRdOptions
 Step
-- 
2.39.5 (Apple Git-154)

Reply via email to