agora inbox for [email protected]help / color / mirror / Atom feed
pgsql: Support FETCH FIRST WITH TIES 547+ messages / 6 participants [nested] [flat]
* pgsql: Support FETCH FIRST WITH TIES @ 2020-04-07 20:25 Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Alvaro Herrera @ 2020-04-07 20:25 UTC (permalink / raw) To: [email protected] Support FETCH FIRST WITH TIES WITH TIES is an option to the FETCH FIRST N ROWS clause (the SQL standard's spelling of LIMIT), where you additionally get rows that compare equal to the last of those N rows by the columns in the mandatory ORDER BY clause. There was a proposal by Andrew Gierth to implement this functionality in a more powerful way that would yield more features, but the other patch had not been finished at this time, so we decided to use this one for now in the spirit of incremental development. Author: Surafel Temesgen <[email protected]> Reviewed-by: Álvaro Herrera <[email protected]> Reviewed-by: Tomas Vondra <[email protected]> Discussion: https://postgr.es/m/CALAY4q9ky7rD_A4vf=FVQvCGngm3LOes-ky0J6euMrg=_Se+ag@mail.gmail.com Discussion: https://postgr.es/m/[email protected] Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/357889eb17bb9c9336c4f324ceb1651da616fe57 Modified Files -------------- doc/src/sgml/ref/select.sgml | 15 +-- src/backend/catalog/sql_features.txt | 2 +- src/backend/executor/nodeLimit.c | 160 +++++++++++++++++++++++++++--- src/backend/nodes/copyfuncs.c | 7 ++ src/backend/nodes/equalfuncs.c | 2 + src/backend/nodes/outfuncs.c | 7 ++ src/backend/nodes/readfuncs.c | 6 ++ src/backend/optimizer/plan/createplan.c | 45 ++++++++- src/backend/optimizer/plan/planner.c | 1 + src/backend/optimizer/util/pathnode.c | 2 + src/backend/parser/analyze.c | 21 ++-- src/backend/parser/gram.y | 117 +++++++++++++++++----- src/backend/parser/parse_clause.c | 15 ++- src/backend/utils/adt/ruleutils.c | 27 ++++-- src/include/catalog/catversion.h | 2 +- src/include/nodes/execnodes.h | 5 + src/include/nodes/nodes.h | 13 +++ src/include/nodes/parsenodes.h | 2 + src/include/nodes/pathnodes.h | 1 + src/include/nodes/plannodes.h | 5 + src/include/optimizer/pathnode.h | 1 + src/include/optimizer/planmain.h | 5 +- src/include/parser/parse_clause.h | 3 +- src/test/regress/expected/limit.out | 167 ++++++++++++++++++++++++++++++++ src/test/regress/sql/limit.sql | 48 +++++++++ 25 files changed, 610 insertions(+), 69 deletions(-) ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: pgsql: Support FETCH FIRST WITH TIES 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> @ 2020-04-11 13:38 ` Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Julien Rouhaud @ 2020-04-11 13:38 UTC (permalink / raw) To: Alvaro Herrera <[email protected]>; +Cc: [email protected] Hi Álvaro, On Tue, Apr 7, 2020 at 10:28 PM Alvaro Herrera <[email protected]> wrote: > > Support FETCH FIRST WITH TIES > > WITH TIES is an option to the FETCH FIRST N ROWS clause (the SQL > standard's spelling of LIMIT), where you additionally get rows that > compare equal to the last of those N rows by the columns in the > mandatory ORDER BY clause. > > There was a proposal by Andrew Gierth to implement this functionality in > a more powerful way that would yield more features, but the other patch > had not been finished at this time, so we decided to use this one for > now in the spirit of incremental development. > > Author: Surafel Temesgen <[email protected]> > Reviewed-by: Álvaro Herrera <[email protected]> > Reviewed-by: Tomas Vondra <[email protected]> > Discussion: https://postgr.es/m/CALAY4q9ky7rD_A4vf=FVQvCGngm3LOes-ky0J6euMrg=_Se+ag@mail.gmail.com > Discussion: https://postgr.es/m/[email protected] > > Branch > ------ > master > > Details > ------- > https://git.postgresql.org/pg/commitdiff/357889eb17bb9c9336c4f324ceb1651da616fe57 > > Modified Files > -------------- > doc/src/sgml/ref/select.sgml | 15 +-- > src/backend/catalog/sql_features.txt | 2 +- > src/backend/executor/nodeLimit.c | 160 +++++++++++++++++++++++++++--- > src/backend/nodes/copyfuncs.c | 7 ++ > src/backend/nodes/equalfuncs.c | 2 + > src/backend/nodes/outfuncs.c | 7 ++ > src/backend/nodes/readfuncs.c | 6 ++ > src/backend/optimizer/plan/createplan.c | 45 ++++++++- > src/backend/optimizer/plan/planner.c | 1 + > src/backend/optimizer/util/pathnode.c | 2 + > src/backend/parser/analyze.c | 21 ++-- > src/backend/parser/gram.y | 117 +++++++++++++++++----- > src/backend/parser/parse_clause.c | 15 ++- > src/backend/utils/adt/ruleutils.c | 27 ++++-- > src/include/catalog/catversion.h | 2 +- > src/include/nodes/execnodes.h | 5 + > src/include/nodes/nodes.h | 13 +++ > src/include/nodes/parsenodes.h | 2 + > src/include/nodes/pathnodes.h | 1 + > src/include/nodes/plannodes.h | 5 + > src/include/optimizer/pathnode.h | 1 + > src/include/optimizer/planmain.h | 5 +- > src/include/parser/parse_clause.h | 3 +- > src/test/regress/expected/limit.out | 167 ++++++++++++++++++++++++++++++++ > src/test/regress/sql/limit.sql | 48 +++++++++ > 25 files changed, 610 insertions(+), 69 deletions(-) > FTR I now get the following when compiling with -Wimplicit-fallthrough -Werror: nodeLimit.c: In function ‘ExecLimit’: nodeLimit.c:136:7: error: this statement may fall through [-Werror=implicit-fallthrough=] 136 | if (ScanDirectionIsForward(direction)) | ^ nodeLimit.c:216:3: note: here 216 | case LIMIT_WINDOWEND_TIES: | ^~~~ It seems that this fall-through comment: [...] else { node->lstate = LIMIT_WINDOWEND_TIES; /* fall-through */ } [...] Is not recognized by my compiler (gcc (Gentoo 9.3.0 p1) 9.3.0). If that's something we should fix, PFA a naive patch for that. Attachments: [text/x-patch] fix_ties_warning.diff (433B, ../../CAOBaU_aLdPGU5wCpaowNLF-Q8328iR7mj1yJAhMOVsdLwY+sdg@mail.gmail.com/2-fix_ties_warning.diff) download | inline diff: diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index 12cfc5177b..99d33fbc21 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -212,6 +212,8 @@ ExecLimit(PlanState *pstate) node->position--; break; } + Assert(node->lstate == LIMIT_WINDOWEND_TIES); + /* fall-through */ case LIMIT_WINDOWEND_TIES: if (ScanDirectionIsForward(direction)) ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: pgsql: Support FETCH FIRST WITH TIES 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> @ 2020-04-11 18:47 ` Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Tom Lane @ 2020-04-11 18:47 UTC (permalink / raw) To: Julien Rouhaud <[email protected]>; +Cc: Alvaro Herrera <[email protected]>; [email protected] Julien Rouhaud <[email protected]> writes: > On Tue, Apr 7, 2020 at 10:28 PM Alvaro Herrera <[email protected]> wrote: >> Support FETCH FIRST WITH TIES > FTR I now get the following when compiling with -Wimplicit-fallthrough -Werror: Yeah, assorted buildfarm animals are mentioning that too. I wonder if we should add that to the default warning options selected by configure? I don't remember if that's been discussed before. > It seems that this fall-through comment: > /* fall-through */ > Is not recognized by my compiler (gcc (Gentoo 9.3.0 p1) 9.3.0). If > that's something we should fix, PFA a naive patch for that. Hmm, I feel like this logic is baroque enough to need more of a rewrite than that :-(. But not sure exactly what would be better, so your patch seems reasonable for now. The comments could use some help too. regards, tom lane ^ permalink raw reply [nested|flat] 547+ messages in thread
* Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> @ 2020-04-12 08:18 ` Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Julien Rouhaud @ 2020-04-12 08:18 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: [email protected] On Sat, Apr 11, 2020 at 02:47:34PM -0400, Tom Lane wrote: > Julien Rouhaud <[email protected]> writes: > > On Tue, Apr 7, 2020 at 10:28 PM Alvaro Herrera <[email protected]> wrote: > >> Support FETCH FIRST WITH TIES > > > FTR I now get the following when compiling with -Wimplicit-fallthrough -Werror: > > Yeah, assorted buildfarm animals are mentioning that too. I wonder > if we should add that to the default warning options selected by > configure? I don't remember if that's been discussed before. > I'm all for it. It seems like a trap easy to catch up early, and we do want to enforce it anyway. I'm attaching a simple patch for that if needed, hopefully with the correct autoconf version. > > It seems that this fall-through comment: > > /* fall-through */ > > Is not recognized by my compiler (gcc (Gentoo 9.3.0 p1) 9.3.0). If > > that's something we should fix, PFA a naive patch for that. > > Hmm, I feel like this logic is baroque enough to need more of a rewrite > than that :-(. But not sure exactly what would be better, so your > patch seems reasonable for now. The comments could use some help too. Yes I just checked the state machine to make sure that the fallthrough was expected, but the comments are now way better, thanks! diff --git a/configure b/configure index 83abe872aa..739b30d5fa 100755 --- a/configure +++ b/configure @@ -5552,6 +5552,97 @@ if test x"$pgac_cv_prog_CXX_cxxflags__Wmissing_format_attribute" = x"yes"; then fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wimplicit-fallthrough, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wimplicit-fallthrough, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wimplicit_fallthrough+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -Wimplicit-fallthrough" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough=yes +else + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" = x"yes"; then + CFLAGS="${CFLAGS} -Wimplicit-fallthrough" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -Wimplicit-fallthrough, for CXXFLAGS" >&5 +$as_echo_n "checking whether ${CXX} supports -Wimplicit-fallthrough, for CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CXX} +CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough=yes +else + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" >&5 +$as_echo "$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" >&6; } +if test x"$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" = x"yes"; then + CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough" +fi + + # This was included in -Wall/-Wformat in older GCC versions { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wformat-security, for CFLAGS" >&5 diff --git a/configure.in b/configure.in index ecdf172396..49816a83dc 100644 --- a/configure.in +++ b/configure.in @@ -496,6 +496,8 @@ if test "$GCC" = yes -a "$ICC" = no; then PGAC_PROG_CXX_CFLAGS_OPT([-Wendif-labels]) PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute]) PGAC_PROG_CXX_CFLAGS_OPT([-Wmissing-format-attribute]) + PGAC_PROG_CC_CFLAGS_OPT([-Wimplicit-fallthrough]) + PGAC_PROG_CXX_CFLAGS_OPT([-Wimplicit-fallthrough]) # This was included in -Wall/-Wformat in older GCC versions PGAC_PROG_CC_CFLAGS_OPT([-Wformat-security]) PGAC_PROG_CXX_CFLAGS_OPT([-Wformat-security]) Attachments: [text/plain] v1-implicit-fallthrough.diff (3.8K, ../../20200412081825.qyo5vwwco3fv4gdo@nol/2-v1-implicit-fallthrough.diff) download | inline diff: diff --git a/configure b/configure index 83abe872aa..739b30d5fa 100755 --- a/configure +++ b/configure @@ -5552,6 +5552,97 @@ if test x"$pgac_cv_prog_CXX_cxxflags__Wmissing_format_attribute" = x"yes"; then fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wimplicit-fallthrough, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wimplicit-fallthrough, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wimplicit_fallthrough+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -Wimplicit-fallthrough" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough=yes +else + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough" = x"yes"; then + CFLAGS="${CFLAGS} -Wimplicit-fallthrough" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -Wimplicit-fallthrough, for CXXFLAGS" >&5 +$as_echo_n "checking whether ${CXX} supports -Wimplicit-fallthrough, for CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CXX} +CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough=yes +else + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" >&5 +$as_echo "$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" >&6; } +if test x"$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough" = x"yes"; then + CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough" +fi + + # This was included in -Wall/-Wformat in older GCC versions { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wformat-security, for CFLAGS" >&5 diff --git a/configure.in b/configure.in index ecdf172396..49816a83dc 100644 --- a/configure.in +++ b/configure.in @@ -496,6 +496,8 @@ if test "$GCC" = yes -a "$ICC" = no; then PGAC_PROG_CXX_CFLAGS_OPT([-Wendif-labels]) PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute]) PGAC_PROG_CXX_CFLAGS_OPT([-Wmissing-format-attribute]) + PGAC_PROG_CC_CFLAGS_OPT([-Wimplicit-fallthrough]) + PGAC_PROG_CXX_CFLAGS_OPT([-Wimplicit-fallthrough]) # This was included in -Wall/-Wformat in older GCC versions PGAC_PROG_CC_CFLAGS_OPT([-Wformat-security]) PGAC_PROG_CXX_CFLAGS_OPT([-Wformat-security]) ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> @ 2020-04-12 14:55 ` Tom Lane <[email protected]> 2020-04-12 15:25 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Mark Dilger <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Tom Lane @ 2020-04-12 14:55 UTC (permalink / raw) To: Julien Rouhaud <[email protected]>; +Cc: [email protected] Julien Rouhaud <[email protected]> writes: > On Sat, Apr 11, 2020 at 02:47:34PM -0400, Tom Lane wrote: >> Yeah, assorted buildfarm animals are mentioning that too. I wonder >> if we should add that to the default warning options selected by >> configure? I don't remember if that's been discussed before. > I'm all for it. It seems like a trap easy to catch up early, and we do want to > enforce it anyway. I'm attaching a simple patch for that if needed, hopefully > with the correct autoconf version. Poking around in the archives, it seems like the only previous formal proposal to add -Wimplicit-fallthrough was in the context of a much more aggressive proposal to make a lot of non-Wall warnings into errors [1], which people did not like. -Wimplicit-fallthrough does have some issues, eg it seems that it's applied at a stage where gcc hasn't yet figured out that elog(ERROR) doesn't return, so you need to add breaks after those. But we had sort of agreed that we could have it on-by-default in one relevant discussion [2], and then failed to pull the trigger. If we do this, I suggest we use -Wimplicit-fallthrough=4, which uses a more-restrictive-than-default definition of how a "fallthrough" comment can be spelled. The default, per the gcc manual, is * -Wimplicit-fallthrough=3 case sensitively matches one of the following regular expressions: *<"-fallthrough"> *<"@fallthrough@"> *<"lint -fallthrough[ \t]*"> *<"[ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)?"> *<"[ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)?"> *<"[ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)?"> which to my eyes is not exactly encouraging a project-standard style for these, plus it seems like it might accept some things we'd rather it didn't. The only more-restrictive alternative, short of disabling the comments altogether, is * -Wimplicit-fallthrough=4 case sensitively matches one of the following regular expressions: *<"-fallthrough"> *<"@fallthrough@"> *<"lint -fallthrough[ \t]*"> *<"[ \t]*FALLTHR(OUGH|U)[ \t]*"> Thoughts? regards, tom lane [1] https://www.postgresql.org/message-id/B9FB1155-B39D-43C9-A7E6-B67E1C59E4CE%40gmail.com [2] https://www.postgresql.org/message-id/flat/E1fDenm-0000C8-IJ%40gemulon.postgresql.org ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> @ 2020-04-12 15:25 ` Mark Dilger <[email protected]> 2020-04-12 15:42 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Mark Dilger @ 2020-04-12 15:25 UTC (permalink / raw) To: Tom Lane <[email protected]>; +Cc: Julien Rouhaud <[email protected]>; [email protected] <[email protected]> > On Apr 12, 2020, at 7:55 AM, Tom Lane <[email protected]> wrote: > > Poking around in the archives, it seems like the only previous formal > proposal to add -Wimplicit-fallthrough was in the context of a much > more aggressive proposal to make a lot of non-Wall warnings into > errors [1], which people did not like. That was from me. > The only more-restrictive alternative, short of disabling > the comments altogether, is > > * -Wimplicit-fallthrough=4 case sensitively matches one of the > following regular expressions: > > *<"-fallthrough"> > *<"@fallthrough@"> > *<"lint -fallthrough[ \t]*"> > *<"[ \t]*FALLTHR(OUGH|U)[ \t]*"> > > Thoughts? Naturally, I'm +1 for this. — Mark Dilger EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 2020-04-12 15:25 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Mark Dilger <[email protected]> @ 2020-04-12 15:42 ` Julien Rouhaud <[email protected]> 2020-04-21 23:31 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Alvaro Herrera <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Julien Rouhaud @ 2020-04-12 15:42 UTC (permalink / raw) To: Mark Dilger <[email protected]>; +Cc: Tom Lane <[email protected]>; [email protected] <[email protected]> On Sun, Apr 12, 2020 at 5:25 PM Mark Dilger <[email protected]> wrote: > > > On Apr 12, 2020, at 7:55 AM, Tom Lane <[email protected]> wrote: > > > > Poking around in the archives, it seems like the only previous formal > > proposal to add -Wimplicit-fallthrough was in the context of a much > > more aggressive proposal to make a lot of non-Wall warnings into > > errors [1], which people did not like. > > That was from me. > > > The only more-restrictive alternative, short of disabling > > the comments altogether, is > > > > * -Wimplicit-fallthrough=4 case sensitively matches one of the > > following regular expressions: > > > > *<"-fallthrough"> > > *<"@fallthrough@"> > > *<"lint -fallthrough[ \t]*"> > > *<"[ \t]*FALLTHR(OUGH|U)[ \t]*"> > > > > Thoughts? > > Naturally, I'm +1 for this. +1 too, obviously. Attachments: [text/x-patch] v2-implicit-fallthrough.diff (3.9K, ../../CAOBaU_Zx6+2eD7G1QYRy3nvHkSn=5m-KD6MRysqmWKqRd1gbUw@mail.gmail.com/2-v2-implicit-fallthrough.diff) download | inline diff: diff --git a/configure b/configure index 83abe872aa..4dfe4fcfe1 100755 --- a/configure +++ b/configure @@ -5552,6 +5552,97 @@ if test x"$pgac_cv_prog_CXX_cxxflags__Wmissing_format_attribute" = x"yes"; then fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wimplicit-fallthrough=4, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wimplicit-fallthrough=4, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -Wimplicit-fallthrough=4" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4=yes +else + pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wimplicit_fallthrough_4" = x"yes"; then + CFLAGS="${CFLAGS} -Wimplicit-fallthrough=4" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -Wimplicit-fallthrough=4, for CXXFLAGS" >&5 +$as_echo_n "checking whether ${CXX} supports -Wimplicit-fallthrough=4, for CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CXX} +CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough=4" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4=yes +else + pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4" >&5 +$as_echo "$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4" >&6; } +if test x"$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_4" = x"yes"; then + CXXFLAGS="${CXXFLAGS} -Wimplicit-fallthrough=4" +fi + + # This was included in -Wall/-Wformat in older GCC versions { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wformat-security, for CFLAGS" >&5 diff --git a/configure.in b/configure.in index ecdf172396..94fba67261 100644 --- a/configure.in +++ b/configure.in @@ -496,6 +496,8 @@ if test "$GCC" = yes -a "$ICC" = no; then PGAC_PROG_CXX_CFLAGS_OPT([-Wendif-labels]) PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute]) PGAC_PROG_CXX_CFLAGS_OPT([-Wmissing-format-attribute]) + PGAC_PROG_CC_CFLAGS_OPT([-Wimplicit-fallthrough=4]) + PGAC_PROG_CXX_CFLAGS_OPT([-Wimplicit-fallthrough=4]) # This was included in -Wall/-Wformat in older GCC versions PGAC_PROG_CC_CFLAGS_OPT([-Wformat-security]) PGAC_PROG_CXX_CFLAGS_OPT([-Wformat-security]) ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 2020-04-12 15:25 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Mark Dilger <[email protected]> 2020-04-12 15:42 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> @ 2020-04-21 23:31 ` Alvaro Herrera <[email protected]> 2020-04-22 02:46 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 0 siblings, 1 reply; 547+ messages in thread From: Alvaro Herrera @ 2020-04-21 23:31 UTC (permalink / raw) To: Julien Rouhaud <[email protected]>; +Cc: Mark Dilger <[email protected]>; Tom Lane <[email protected]>; [email protected] <[email protected]> Do we intend to see this done in the current cycle? -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services ^ permalink raw reply [nested|flat] 547+ messages in thread
* Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Re: pgsql: Support FETCH FIRST WITH TIES Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Re: pgsql: Support FETCH FIRST WITH TIES Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 2020-04-12 15:25 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Mark Dilger <[email protected]> 2020-04-12 15:42 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-21 23:31 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Alvaro Herrera <[email protected]> @ 2020-04-22 02:46 ` Tom Lane <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Tom Lane @ 2020-04-22 02:46 UTC (permalink / raw) To: Alvaro Herrera <[email protected]>; +Cc: Julien Rouhaud <[email protected]>; Mark Dilger <[email protected]>; [email protected] <[email protected]> Alvaro Herrera <[email protected]> writes: > Do we intend to see this done in the current cycle? I don't have an objection to doing it now. It's just a new compiler warning option, it shouldn't be able to break any code. (Plus there's plenty of time to revert, if somehow it causes a problem.) regards, tom lane ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart5129932.5fSG56mABF Content-Disposition: attachment; filename="v2-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
* [PATCH v2a 1/4] Add ternary reloption type @ 2025-09-04 14:34 Nikolay Shaplov <[email protected]> 0 siblings, 0 replies; 547+ messages in thread From: Nikolay Shaplov @ 2025-09-04 14:34 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "ternary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as ternary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for ternary reloptions in future, but now it checks the behaviour of reloptions that would become ternary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f..1c99f79ab0 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) ternary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478..f5980dafcb 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) ternary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart4155600.3ZeAukHxDK Content-Disposition: attachment; filename="v2a-0002-Introduce-ternary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v2a-0002-Introduce-ternary-reloptions.patch" ^ permalink raw reply [nested|flat] 547+ messages in thread
end of thread, other threads:[~2025-09-04 14:34 UTC | newest] Thread overview: 547+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-04-07 20:25 pgsql: Support FETCH FIRST WITH TIES Alvaro Herrera <[email protected]> 2020-04-11 13:38 ` Julien Rouhaud <[email protected]> 2020-04-11 18:47 ` Tom Lane <[email protected]> 2020-04-12 08:18 ` Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-12 14:55 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 2020-04-12 15:25 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Mark Dilger <[email protected]> 2020-04-12 15:42 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Julien Rouhaud <[email protected]> 2020-04-21 23:31 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Alvaro Herrera <[email protected]> 2020-04-22 02:46 ` Re: Add "-Wimplicit-fallthrough" to default flags (was Re: pgsql: Support FETCH FIRST WITH TIES) Tom Lane <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]> 2025-09-04 14:34 [PATCH v2a 1/4] Add ternary reloption type Nikolay Shaplov <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox