agora inbox for pgsql-hackers@postgresql.orghelp / color / mirror / Atom feed
[PATCH v1 1/4] Add trenary reloption type 268+ messages / 2 participants [nested] [flat]
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v1 1/4] Add trenary reloption type @ 2025-08-30 12:12 Nikolay Shaplov <dhyan@nataraj.su> 0 siblings, 0 replies; 268+ messages in thread From: Nikolay Shaplov @ 2025-08-30 12:12 UTC (permalink / raw) There is a tendency for boolean reloptions in PostgreSQL code, one with "on" and "off" values, to be replaced with options with "on", "off", "[use_global_settings]" behaviour. For `vacuum_index_cleanup" and gist's `buffering` reloption such behavior have been implemented as enum-tyoe option. For vacuum_truncate this behaviour have been umplemented by adding additional `is_set` flag to `bytea` representation of the reloptions. Both solutions looks like workaround hacks to implement option with three available states. This patch introduce "trenary" reloption type, that behave like bool option, but also has an additional "unset" state. This state may be reachable only by not setting or RESETting an option, like in `vacuum_truncate` option, or it may have some text alias that allow user to explicitly set it, like "auto" in `vacuum_index_cleanup` or gist's `buffering` `vacuum_truncate`, `vacuum_index_cleanup` and gist's `buffering` reloptions are reimplemented as trenary reloptions without significant behaviour changes. --- This patch is split into four parts, to help reviewer grasp the login behind it. I guess it is better to commit it as a single commit --- Part1: Add regression tests that would be tests for trenary reloptions in future, but now it checks the behaviour of reloptions that would become trenary. There behaviour should not change, so adding tests before changing anything. These tests should pass before applying the patch, and after it. --- src/test/regress/expected/reloptions.out | 36 ++++++++++++++++++++++++ src/test/regress/sql/reloptions.sql | 21 ++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index 9de19b4e3f1..e32431ca067 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -98,6 +98,42 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; {fillfactor=13,autovacuum_enabled=false} (1 row) +-- Tests for future (FIXME) trenary options +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=true} +(1 row) + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +------------------------ + {vacuum_truncate=fals} +(1 row) + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +--------------------------- + {vacuum_index_cleanup=on} +(1 row) + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +----------------------------- + {vacuum_index_cleanup=auto} +(1 row) + -- Test vacuum_truncate option DROP TABLE reloptions_test; CREATE TEMP TABLE reloptions_test(i INT NOT NULL, j text) diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 24fbe0b478d..051142eed5f 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -59,6 +59,27 @@ UPDATE pg_class ALTER TABLE reloptions_test RESET (illegal_option); SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +-- Tests for future (FIXME) trenary options + +-- behave as boolean option: accept unassigned name and truncated value +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- preferred "true" alias is used when storing +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +-- custom "third" value is available +DROP TABLE reloptions_test; +CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=auto); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + -- Test vacuum_truncate option DROP TABLE reloptions_test; -- 2.39.2 --nextPart6784952.tM3a2QDmDi Content-Disposition: attachment; filename="v1-0002-Introduce-trenary-reloptions.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="unicode-2-0-utf-8"; name="v1-0002-Introduce-trenary-reloptions.patch" ^ permalink raw reply [nested|flat] 268+ messages in thread
* [PATCH v8 1/1] handle concurrent drop in database-wide vacuum @ 2026-06-30 15:29 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 268+ messages in thread From: Nathan Bossart @ 2026-06-30 15:29 UTC (permalink / raw) --- src/backend/commands/analyze.c | 3 ++- src/backend/commands/vacuum.c | 23 ++++++++++++++++++----- src/include/commands/vacuum.h | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f66e80b757c..c28b9dae983 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -157,7 +157,8 @@ analyze_rel(Oid relid, RangeVar *relation, */ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel), onerel->rd_rel, - params->options & ~VACOPT_VACUUM)) + params->options & ~VACOPT_VACUUM, + false)) { relation_close(onerel, ShareUpdateExclusiveLock); return; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index a4abb29cf64..a402d2330f0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -718,9 +718,10 @@ vacuum(List *relations, const VacuumParams *params, BufferAccessStrategy bstrate */ bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options) + uint32 options, bool missing_ok) { char *relname; + bool is_missing = false; Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); @@ -733,9 +734,20 @@ vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, */ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) || - pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK) + pg_class_aclcheck_ext(relid, GetUserId(), ACL_MAINTAIN, + missing_ok ? &is_missing : NULL) == ACLCHECK_OK) return true; + /* + * If the relation was concurrently dropped, nothing to do. Note that + * this is only reachable when the caller specified missing_ok. + */ + if (is_missing) + { + Assert(missing_ok); + return false; + } + relname = NameStr(reltuple->relname); if ((options & VACOPT_VACUUM) != 0) @@ -956,7 +968,7 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, * Make a returnable VacuumRelation for this rel if the user has the * required privileges. */ - if (vacuum_is_permitted_for_relation(relid, classForm, options)) + if (vacuum_is_permitted_for_relation(relid, classForm, options, false)) { oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, @@ -1069,7 +1081,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) continue; /* check permissions of relation */ - if (!vacuum_is_permitted_for_relation(relid, classForm, options)) + if (!vacuum_is_permitted_for_relation(relid, classForm, options, true)) continue; /* @@ -2115,7 +2127,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params, */ if (!vacuum_is_permitted_for_relation(priv_relid, rel->rd_rel, - params.options & ~VACOPT_ANALYZE)) + params.options & ~VACOPT_ANALYZE, + false)) { relation_close(rel, lmode); PopActiveSnapshot(); diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 956d9cea36d..e62f23748dc 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -389,7 +389,7 @@ extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(bool is_analyze); extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, - uint32 options); + uint32 options, bool missing_ok); extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, uint32 options, bool verbose, LOCKMODE lmode); -- 2.50.1 (Apple Git-155) --dDwC+h/KQNl/aRwi-- ^ permalink raw reply [nested|flat] 268+ messages in thread
end of thread, other threads:[~2026-06-30 15:29 UTC | newest] Thread overview: 268+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2025-08-30 12:12 [PATCH v1 1/4] Add trenary reloption type Nikolay Shaplov <dhyan@nataraj.su> 2026-06-30 15:29 [PATCH v8 1/1] handle concurrent drop in database-wide vacuum Nathan Bossart <nathan@postgresql.org>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox