Thread
-
[PATCH v2a 3/4] Add alias to be used as "unset" state.
Nikolay Shaplov <dhyan@nataraj.su> — 2025-09-04T16:22:21Z
Add `unset_alias` string parameter to ternary reloption definition. This will allow user explicitly switch ternary option to "unset" state. Use this feature to implement `vacuum_index_cleanup` and gist's `buffering` reloptions as ternary reloptions --- src/backend/access/common/reloptions.c | 91 +++++++++++--------------- src/backend/access/gist/gistbuild.c | 4 +- src/backend/commands/vacuum.c | 11 ++-- src/include/access/gist_private.h | 10 +-- src/include/access/reloptions.h | 7 +- src/include/utils/rel.h | 10 +-- src/test/regress/expected/gist.out | 3 +- 7 files changed, 54 insertions(+), 82 deletions(-) diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index f543f11001..3637646641 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -170,6 +170,27 @@ static relopt_ternary ternaryRelOpts[] = RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, ShareUpdateExclusiveLock }, + NULL, + TERNARY_UNSET + }, + { + { + "vacuum_index_cleanup", + "Controls index vacuuming and index cleanup", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + ShareUpdateExclusiveLock + }, + "auto", + TERNARY_UNSET + }, + { + { + "buffering", + "Enables buffering build for this GiST index", + RELOPT_KIND_GIST, + AccessExclusiveLock + }, + "auto", TERNARY_UNSET }, /* list terminator */ @@ -489,30 +510,6 @@ static relopt_real realRelOpts[] = {{NULL}} }; -/* values from StdRdOptIndexCleanup */ -static relopt_enum_elt_def StdRdOptIndexCleanupValues[] = -{ - {"auto", STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO}, - {"on", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, - {"off", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, - {"true", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, - {"false", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, - {"yes", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, - {"no", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, - {"1", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, - {"0", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, - {(const char *) NULL} /* list terminator */ -}; - -/* values from GistOptBufferingMode */ -static relopt_enum_elt_def gistBufferingOptValues[] = -{ - {"auto", GIST_OPTION_BUFFERING_AUTO}, - {"on", GIST_OPTION_BUFFERING_ON}, - {"off", GIST_OPTION_BUFFERING_OFF}, - {(const char *) NULL} /* list terminator */ -}; - /* values from ViewOptCheckOption */ static relopt_enum_elt_def viewCheckOptValues[] = { @@ -524,28 +521,6 @@ static relopt_enum_elt_def viewCheckOptValues[] = static relopt_enum enumRelOpts[] = { - { - { - "vacuum_index_cleanup", - "Controls index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, - ShareUpdateExclusiveLock - }, - StdRdOptIndexCleanupValues, - STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO, - gettext_noop("Valid values are \"on\", \"off\", and \"auto\".") - }, - { - { - "buffering", - "Enables buffering build for this GiST index", - RELOPT_KIND_GIST, - AccessExclusiveLock - }, - gistBufferingOptValues, - GIST_OPTION_BUFFERING_AUTO, - gettext_noop("Valid values are \"on\", \"off\", and \"auto\".") - }, { { "check_option", @@ -913,13 +888,14 @@ add_local_bool_reloption(local_relopts *relopts, const char *name, */ static relopt_ternary * init_ternary_reloption(bits32 kinds, const char *name, const char *desc, - ternary default_val, LOCKMODE lockmode) + ternary default_val, const char* unset_alias, LOCKMODE lockmode) { relopt_ternary *newoption; newoption = (relopt_ternary *) allocate_reloption(kinds, RELOPT_TYPE_TERNARY, name, desc, lockmode); newoption->default_val = default_val; + newoption->unset_alias = unset_alias; return newoption; } @@ -930,10 +906,10 @@ init_ternary_reloption(bits32 kinds, const char *name, const char *desc, */ void add_ternary_reloption(bits32 kinds, const char *name, const char *desc, - ternary default_val, LOCKMODE lockmode) + ternary default_val, const char* unset_alias, LOCKMODE lockmode) { relopt_ternary *newoption = init_ternary_reloption(kinds, name, desc, - default_val, lockmode); + default_val, unset_alias, lockmode); add_reloption((relopt_gen *) newoption); } @@ -947,11 +923,11 @@ add_ternary_reloption(bits32 kinds, const char *name, const char *desc, void add_local_ternary_reloption(local_relopts *relopts, const char *name, const char *desc, ternary default_val, - int offset) + const char* unset_alias, int offset) { relopt_ternary *newoption = init_ternary_reloption(RELOPT_KIND_LOCAL, name, desc, - default_val, 0); + default_val, unset_alias, 0); add_local_reloption(relopts, (relopt_gen *) newoption, offset); } @@ -1692,8 +1668,19 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, case RELOPT_TYPE_TERNARY: { bool b; + relopt_ternary *opt = (relopt_ternary *) option->gen; + parsed = parse_bool(value, &b); option->values.ternary_val = b ? TERNARY_TRUE : TERNARY_FALSE; + + if (!parsed && opt->unset_alias) + { + if (pg_strcasecmp(value, opt->unset_alias) == 0) + { + option->values.ternary_val = TERNARY_UNSET; + parsed = true; + } + } if (validate && !parsed) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1988,7 +1975,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) offsetof(StdRdOptions, user_catalog_table)}, {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)}, - {"vacuum_index_cleanup", RELOPT_TYPE_ENUM, + {"vacuum_index_cleanup", RELOPT_TYPE_TERNARY, offsetof(StdRdOptions, vacuum_index_cleanup)}, {"vacuum_truncate", RELOPT_TYPE_TERNARY, offsetof(StdRdOptions, vacuum_truncate)}, diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 9b2ec9815f..7f641f7825 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -213,9 +213,9 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) */ if (options) { - if (options->buffering_mode == GIST_OPTION_BUFFERING_ON) + if (options->buffering_mode == TERNARY_TRUE) buildstate.buildMode = GIST_BUFFERING_STATS; - else if (options->buffering_mode == GIST_OPTION_BUFFERING_OFF) + else if (options->buffering_mode == TERNARY_FALSE) buildstate.buildMode = GIST_BUFFERING_DISABLED; else /* must be "auto" */ buildstate.buildMode = GIST_BUFFERING_AUTO; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 977babff54..61b4bdb682 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2175,22 +2175,21 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (params.index_cleanup == VACOPTVALUE_UNSPECIFIED) { - StdRdOptIndexCleanup vacuum_index_cleanup; + ternary vacuum_index_cleanup; if (rel->rd_options == NULL) - vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO; + vacuum_index_cleanup = TERNARY_UNSET; else vacuum_index_cleanup = ((StdRdOptions *) rel->rd_options)->vacuum_index_cleanup; - if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO) + if (vacuum_index_cleanup == TERNARY_UNSET) params.index_cleanup = VACOPTVALUE_AUTO; - else if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON) + else if (vacuum_index_cleanup == TERNARY_TRUE) params.index_cleanup = VACOPTVALUE_ENABLED; else { - Assert(vacuum_index_cleanup == - STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF); + Assert(vacuum_index_cleanup == TERNARY_FALSE); params.index_cleanup = VACOPTVALUE_DISABLED; } } diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 39404ec7cd..a931c988fb 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -380,14 +380,6 @@ typedef struct GISTBuildBuffers int rootlevel; } GISTBuildBuffers; -/* GiSTOptions->buffering_mode values */ -typedef enum GistOptBufferingMode -{ - GIST_OPTION_BUFFERING_AUTO, - GIST_OPTION_BUFFERING_ON, - GIST_OPTION_BUFFERING_OFF, -} GistOptBufferingMode; - /* * Storage type for GiST's reloptions */ @@ -395,7 +387,7 @@ typedef struct GiSTOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ - GistOptBufferingMode buffering_mode; /* buffering build mode */ + ternary buffering_mode; /* buffering build mode */ } GiSTOptions; /* gist.c */ diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index a436697658..552c89869f 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -99,6 +99,7 @@ typedef struct relopt_bool typedef struct relopt_rernary { relopt_gen gen; + const char *unset_alias; /* word that will be treated as unset value */ int default_val; } relopt_ternary; @@ -191,7 +192,8 @@ extern relopt_kind add_reloption_kind(void); extern void add_bool_reloption(bits32 kinds, const char *name, const char *desc, bool default_val, LOCKMODE lockmode); extern void add_ternary_reloption(bits32 kinds, const char *name, - const char *desc, int default_val, LOCKMODE lockmode); + const char *desc, ternary default_val, + const char* unset_alias, LOCKMODE lockmode); extern void add_int_reloption(bits32 kinds, const char *name, const char *desc, int default_val, int min_val, int max_val, LOCKMODE lockmode); @@ -213,7 +215,8 @@ extern void add_local_bool_reloption(local_relopts *relopts, const char *name, int offset); extern void add_local_ternary_reloption(local_relopts *relopts, const char *name, const char *desc, - ternary default_val, int offset); + ternary default_val, const char* unset_alias, + int offset); extern void add_local_int_reloption(local_relopts *relopts, const char *name, const char *desc, int default_val, int min_val, int max_val, int offset); diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 7346d618f9..95a18c6d16 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -329,14 +329,6 @@ typedef struct AutoVacOpts float8 analyze_scale_factor; } AutoVacOpts; -/* StdRdOptions->vacuum_index_cleanup values */ -typedef enum StdRdOptIndexCleanup -{ - STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0, - STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF, - STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON, -} StdRdOptIndexCleanup; - typedef struct StdRdOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ @@ -345,7 +337,7 @@ typedef struct StdRdOptions AutoVacOpts autovacuum; /* autovacuum-related options */ 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 */ + ternary vacuum_index_cleanup; /* controls index vacuuming */ ternary vacuum_truncate; /* enables vacuum to truncate a relation */ /* diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index c75bbb23b6..76751d1859 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -12,8 +12,7 @@ create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = au drop index gist_pointidx2, gist_pointidx3, gist_pointidx4; -- Make sure bad values are refused create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value); -ERROR: invalid value for enum option "buffering": invalid_value -DETAIL: Valid values are "on", "off", and "auto". +ERROR: invalid value for ternary option "buffering": invalid_value create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9); ERROR: value 9 out of bounds for option "fillfactor" DETAIL: Valid values are between "10" and "100". -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0004-Extra-tests.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0004-Extra-tests.patch"